[Home] Elastic home page redesign (#70571)
Co-authored-by: Catherine Liu <catherine.liu@elastic.co> Co-authored-by: Ryan Keairns <contactryank@gmail.com> Co-authored-by: Catherine Liu <catherineqliu@outlook.com> Co-authored-by: Michael Marcialis <michael.marcialis@elastic.co>
This commit is contained in:
parent
638df5820c
commit
532f2d70e8
|
@ -147,7 +147,7 @@ exports[`CollapsibleNav renders links grouped by category 1`] = `
|
||||||
"baseUrl": "/",
|
"baseUrl": "/",
|
||||||
"category": Object {
|
"category": Object {
|
||||||
"euiIconType": "logoSecurity",
|
"euiIconType": "logoSecurity",
|
||||||
"id": "security",
|
"id": "securitySolution",
|
||||||
"label": "Security",
|
"label": "Security",
|
||||||
"order": 4000,
|
"order": 4000,
|
||||||
},
|
},
|
||||||
|
@ -1393,11 +1393,11 @@ exports[`CollapsibleNav renders links grouped by category 1`] = `
|
||||||
</EuiAccordion>
|
</EuiAccordion>
|
||||||
</EuiCollapsibleNavGroup>
|
</EuiCollapsibleNavGroup>
|
||||||
<EuiCollapsibleNavGroup
|
<EuiCollapsibleNavGroup
|
||||||
data-test-subj="collapsibleNavGroup-security"
|
data-test-subj="collapsibleNavGroup-securitySolution"
|
||||||
iconType="logoSecurity"
|
iconType="logoSecurity"
|
||||||
initialIsOpen={true}
|
initialIsOpen={true}
|
||||||
isCollapsible={true}
|
isCollapsible={true}
|
||||||
key="security"
|
key="securitySolution"
|
||||||
onToggle={[Function]}
|
onToggle={[Function]}
|
||||||
title="Security"
|
title="Security"
|
||||||
>
|
>
|
||||||
|
@ -1433,7 +1433,7 @@ exports[`CollapsibleNav renders links grouped by category 1`] = `
|
||||||
</EuiFlexGroup>
|
</EuiFlexGroup>
|
||||||
}
|
}
|
||||||
className="euiCollapsibleNavGroup euiCollapsibleNavGroup--withHeading"
|
className="euiCollapsibleNavGroup euiCollapsibleNavGroup--withHeading"
|
||||||
data-test-subj="collapsibleNavGroup-security"
|
data-test-subj="collapsibleNavGroup-securitySolution"
|
||||||
id="mockId"
|
id="mockId"
|
||||||
initialIsOpen={true}
|
initialIsOpen={true}
|
||||||
onToggle={[Function]}
|
onToggle={[Function]}
|
||||||
|
@ -1441,7 +1441,7 @@ exports[`CollapsibleNav renders links grouped by category 1`] = `
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="euiAccordion euiAccordion-isOpen euiCollapsibleNavGroup euiCollapsibleNavGroup--withHeading"
|
className="euiAccordion euiAccordion-isOpen euiCollapsibleNavGroup euiCollapsibleNavGroup--withHeading"
|
||||||
data-test-subj="collapsibleNavGroup-security"
|
data-test-subj="collapsibleNavGroup-securitySolution"
|
||||||
onToggle={[Function]}
|
onToggle={[Function]}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -2283,10 +2283,12 @@ exports[`Header renders 2`] = `
|
||||||
data-test-subj="headerGlobalNav"
|
data-test-subj="headerGlobalNav"
|
||||||
>
|
>
|
||||||
<EuiHeader
|
<EuiHeader
|
||||||
|
id="headerGlobalNav"
|
||||||
position="fixed"
|
position="fixed"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="euiHeader euiHeader--default euiHeader--fixed"
|
className="euiHeader euiHeader--default euiHeader--fixed"
|
||||||
|
id="headerGlobalNav"
|
||||||
>
|
>
|
||||||
<EuiHeaderSection
|
<EuiHeaderSection
|
||||||
grow={false}
|
grow={false}
|
||||||
|
@ -6494,10 +6496,12 @@ exports[`Header renders 3`] = `
|
||||||
data-test-subj="headerGlobalNav"
|
data-test-subj="headerGlobalNav"
|
||||||
>
|
>
|
||||||
<EuiHeader
|
<EuiHeader
|
||||||
|
id="headerGlobalNav"
|
||||||
position="fixed"
|
position="fixed"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="euiHeader euiHeader--default euiHeader--fixed"
|
className="euiHeader euiHeader--default euiHeader--fixed"
|
||||||
|
id="headerGlobalNav"
|
||||||
>
|
>
|
||||||
<EuiHeaderSection
|
<EuiHeaderSection
|
||||||
grow={false}
|
grow={false}
|
||||||
|
@ -11306,10 +11310,12 @@ exports[`Header renders 4`] = `
|
||||||
data-test-subj="headerGlobalNav"
|
data-test-subj="headerGlobalNav"
|
||||||
>
|
>
|
||||||
<EuiHeader
|
<EuiHeader
|
||||||
|
id="headerGlobalNav"
|
||||||
position="fixed"
|
position="fixed"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="euiHeader euiHeader--default euiHeader--fixed"
|
className="euiHeader euiHeader--default euiHeader--fixed"
|
||||||
|
id="headerGlobalNav"
|
||||||
>
|
>
|
||||||
<EuiHeaderSection
|
<EuiHeaderSection
|
||||||
grow={false}
|
grow={false}
|
||||||
|
|
|
@ -125,7 +125,7 @@ export function Header({
|
||||||
<>
|
<>
|
||||||
<LoadingIndicator loadingCount$={observables.loadingCount$} />
|
<LoadingIndicator loadingCount$={observables.loadingCount$} />
|
||||||
<header className={className} data-test-subj="headerGlobalNav">
|
<header className={className} data-test-subj="headerGlobalNav">
|
||||||
<EuiHeader position="fixed">
|
<EuiHeader position="fixed" id="headerGlobalNav">
|
||||||
<EuiHeaderSection grow={false}>
|
<EuiHeaderSection grow={false}>
|
||||||
{navType === 'modern' ? (
|
{navType === 'modern' ? (
|
||||||
<EuiHeaderSectionItem border="right" className="header__toggleNavButtonSection">
|
<EuiHeaderSectionItem border="right" className="header__toggleNavButtonSection">
|
||||||
|
|
|
@ -3,5 +3,5 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.kbnGlobalBannerList__item + .kbnGlobalBannerList__item {
|
.kbnGlobalBannerList__item + .kbnGlobalBannerList__item {
|
||||||
margin-top: $euiSize;
|
margin-top: $euiSizeS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ export const DEFAULT_APP_CATEGORIES = Object.freeze({
|
||||||
order: 3000,
|
order: 3000,
|
||||||
},
|
},
|
||||||
security: {
|
security: {
|
||||||
id: 'security',
|
id: 'securitySolution',
|
||||||
label: i18n.translate('core.ui.securityNavList.label', {
|
label: i18n.translate('core.ui.securityNavList.label', {
|
||||||
defaultMessage: 'Security',
|
defaultMessage: 'Security',
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -4,5 +4,6 @@
|
||||||
"server": true,
|
"server": true,
|
||||||
"ui": true,
|
"ui": true,
|
||||||
"requiredPlugins": ["management"],
|
"requiredPlugins": ["management"],
|
||||||
"requiredBundles": ["kibanaReact"]
|
"optionalPlugins": ["home"],
|
||||||
|
"requiredBundles": ["kibanaReact", "home"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,6 +114,21 @@ export class AdvancedSettingsComponent extends Component<
|
||||||
filteredSettings: this.mapSettings(Query.execute(query, this.settings)),
|
filteredSettings: this.mapSettings(Query.execute(query, this.settings)),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// scrolls to setting provided in the URL hash
|
||||||
|
const { hash } = window.location;
|
||||||
|
if (hash !== '') {
|
||||||
|
setTimeout(() => {
|
||||||
|
const id = hash.replace('#', '');
|
||||||
|
const element = document.getElementById(id);
|
||||||
|
const globalNavOffset = document.getElementById('headerGlobalNav')?.offsetHeight || 0;
|
||||||
|
|
||||||
|
if (element) {
|
||||||
|
element.scrollIntoView();
|
||||||
|
window.scrollBy(0, -globalNavOffset); // offsets scroll by height of the global nav
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
|
|
@ -15,6 +15,7 @@ exports[`Field for array setting should render as read only if saving is disable
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="array:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -87,6 +88,7 @@ exports[`Field for array setting should render as read only with help text if ov
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="array:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -147,6 +149,7 @@ exports[`Field for array setting should render custom setting icon if it is cust
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="array:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -208,6 +211,7 @@ exports[`Field for array setting should render default value if there is no user
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="array:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -258,6 +262,7 @@ exports[`Field for array setting should render unsaved value if there are unsave
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="array:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -359,6 +364,7 @@ exports[`Field for array setting should render user value if there is user value
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="array:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -426,6 +432,7 @@ exports[`Field for boolean setting should render as read only if saving is disab
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="boolean:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -504,6 +511,7 @@ exports[`Field for boolean setting should render as read only with help text if
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="boolean:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -570,6 +578,7 @@ exports[`Field for boolean setting should render custom setting icon if it is cu
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="boolean:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -637,6 +646,7 @@ exports[`Field for boolean setting should render default value if there is no us
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="boolean:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -693,6 +703,7 @@ exports[`Field for boolean setting should render unsaved value if there are unsa
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="boolean:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -796,6 +807,7 @@ exports[`Field for boolean setting should render user value if there is user val
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="boolean:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -869,6 +881,7 @@ exports[`Field for image setting should render as read only if saving is disable
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="image:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -943,6 +956,7 @@ exports[`Field for image setting should render as read only with help text if ov
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="image:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -1001,6 +1015,7 @@ exports[`Field for image setting should render custom setting icon if it is cust
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="image:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -1064,6 +1079,7 @@ exports[`Field for image setting should render default value if there is no user
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="image:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -1116,6 +1132,7 @@ exports[`Field for image setting should render unsaved value if there are unsave
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="image:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -1214,6 +1231,7 @@ exports[`Field for image setting should render user value if there is user value
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="image:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -1317,6 +1335,7 @@ exports[`Field for json setting should render as read only if saving is disabled
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="json:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -1412,6 +1431,7 @@ exports[`Field for json setting should render as read only with help text if ove
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="json:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -1492,6 +1512,7 @@ exports[`Field for json setting should render custom setting icon if it is custo
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="json:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -1598,6 +1619,7 @@ exports[`Field for json setting should render default value if there is no user
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="json:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -1685,6 +1707,7 @@ exports[`Field for json setting should render unsaved value if there are unsaved
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="json:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -1809,6 +1832,7 @@ exports[`Field for json setting should render user value if there is user value
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="json:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -1896,6 +1920,7 @@ exports[`Field for markdown setting should render as read only if saving is disa
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="markdown:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -1988,6 +2013,7 @@ exports[`Field for markdown setting should render as read only with help text if
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="markdown:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -2068,6 +2094,7 @@ exports[`Field for markdown setting should render custom setting icon if it is c
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="markdown:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -2149,6 +2176,7 @@ exports[`Field for markdown setting should render default value if there is no u
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="markdown:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -2219,6 +2247,7 @@ exports[`Field for markdown setting should render unsaved value if there are uns
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="markdown:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -2336,6 +2365,7 @@ exports[`Field for markdown setting should render user value if there is user va
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="markdown:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -2423,6 +2453,7 @@ exports[`Field for number setting should render as read only if saving is disabl
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="number:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -2495,6 +2526,7 @@ exports[`Field for number setting should render as read only with help text if o
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="number:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -2555,6 +2587,7 @@ exports[`Field for number setting should render custom setting icon if it is cus
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="number:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -2616,6 +2649,7 @@ exports[`Field for number setting should render default value if there is no use
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="number:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -2666,6 +2700,7 @@ exports[`Field for number setting should render unsaved value if there are unsav
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="number:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -2763,6 +2798,7 @@ exports[`Field for number setting should render user value if there is user valu
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="number:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -2830,6 +2866,7 @@ exports[`Field for select setting should render as read only if saving is disabl
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="select:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -2918,6 +2955,7 @@ exports[`Field for select setting should render as read only with help text if o
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="select:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -2994,6 +3032,7 @@ exports[`Field for select setting should render custom setting icon if it is cus
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="select:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -3071,6 +3110,7 @@ exports[`Field for select setting should render default value if there is no use
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="select:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -3137,6 +3177,7 @@ exports[`Field for select setting should render unsaved value if there are unsav
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="select:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -3250,6 +3291,7 @@ exports[`Field for select setting should render user value if there is user valu
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="select:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -3333,6 +3375,7 @@ exports[`Field for string setting should render as read only if saving is disabl
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="string:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -3405,6 +3448,7 @@ exports[`Field for string setting should render as read only with help text if o
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="string:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -3465,6 +3509,7 @@ exports[`Field for string setting should render custom setting icon if it is cus
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="string:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -3526,6 +3571,7 @@ exports[`Field for string setting should render default value if there is no use
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="string:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -3576,6 +3622,7 @@ exports[`Field for string setting should render unsaved value if there are unsav
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="string:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -3673,6 +3720,7 @@ exports[`Field for string setting should render user value if there is user valu
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="string:test:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -3740,6 +3788,7 @@ exports[`Field for stringWithValidation setting should render as read only if sa
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="string:test-validation:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -3812,6 +3861,7 @@ exports[`Field for stringWithValidation setting should render as read only with
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="string:test-validation:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -3872,6 +3922,7 @@ exports[`Field for stringWithValidation setting should render custom setting ico
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="string:test-validation:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -3933,6 +3984,7 @@ exports[`Field for stringWithValidation setting should render default value if t
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="string:test-validation:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -3983,6 +4035,7 @@ exports[`Field for stringWithValidation setting should render unsaved value if t
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="string:test-validation:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
@ -4080,6 +4133,7 @@ exports[`Field for stringWithValidation setting should render user value if ther
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
id="string:test-validation:setting"
|
||||||
title={
|
title={
|
||||||
<h3>
|
<h3>
|
||||||
<span
|
<span
|
||||||
|
|
|
@ -673,6 +673,7 @@ export class Field extends PureComponent<FieldProps> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EuiDescribedFormGroup
|
<EuiDescribedFormGroup
|
||||||
|
id={id}
|
||||||
className={className}
|
className={className}
|
||||||
title={this.renderTitle(setting)}
|
title={this.renderTitle(setting)}
|
||||||
description={this.renderDescription(setting)}
|
description={this.renderDescription(setting)}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { CoreSetup, Plugin } from 'kibana/public';
|
import { CoreSetup, Plugin } from 'kibana/public';
|
||||||
|
import { FeatureCatalogueCategory } from '../../home/public';
|
||||||
import { ComponentRegistry } from './component_registry';
|
import { ComponentRegistry } from './component_registry';
|
||||||
import { AdvancedSettingsSetup, AdvancedSettingsStart, AdvancedSettingsPluginSetup } from './types';
|
import { AdvancedSettingsSetup, AdvancedSettingsStart, AdvancedSettingsPluginSetup } from './types';
|
||||||
|
|
||||||
|
@ -29,7 +30,7 @@ const title = i18n.translate('advancedSettings.advancedSettingsLabel', {
|
||||||
|
|
||||||
export class AdvancedSettingsPlugin
|
export class AdvancedSettingsPlugin
|
||||||
implements Plugin<AdvancedSettingsSetup, AdvancedSettingsStart, AdvancedSettingsPluginSetup> {
|
implements Plugin<AdvancedSettingsSetup, AdvancedSettingsStart, AdvancedSettingsPluginSetup> {
|
||||||
public setup(core: CoreSetup, { management }: AdvancedSettingsPluginSetup) {
|
public setup(core: CoreSetup, { management, home }: AdvancedSettingsPluginSetup) {
|
||||||
const kibanaSection = management.sections.section.kibana;
|
const kibanaSection = management.sections.section.kibana;
|
||||||
|
|
||||||
kibanaSection.registerApp({
|
kibanaSection.registerApp({
|
||||||
|
@ -44,6 +45,21 @@ export class AdvancedSettingsPlugin
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (home) {
|
||||||
|
home.featureCatalogue.register({
|
||||||
|
id: 'advanced_settings',
|
||||||
|
title,
|
||||||
|
description: i18n.translate('advancedSettings.featureCatalogueTitle', {
|
||||||
|
defaultMessage:
|
||||||
|
'Customize your Kibana experience — change the date format, turn on dark mode, and more.',
|
||||||
|
}),
|
||||||
|
icon: 'gear',
|
||||||
|
path: '/app/management/kibana/settings',
|
||||||
|
showOnHomePage: false,
|
||||||
|
category: FeatureCatalogueCategory.ADMIN,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
component: component.setup,
|
component: component.setup,
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ComponentRegistry } from './component_registry';
|
import { ComponentRegistry } from './component_registry';
|
||||||
|
import { HomePublicPluginSetup } from '../../home/public';
|
||||||
|
|
||||||
import { ManagementSetup } from '../../management/public';
|
import { ManagementSetup } from '../../management/public';
|
||||||
|
|
||||||
export interface AdvancedSettingsSetup {
|
export interface AdvancedSettingsSetup {
|
||||||
|
@ -29,6 +31,7 @@ export interface AdvancedSettingsStart {
|
||||||
|
|
||||||
export interface AdvancedSettingsPluginSetup {
|
export interface AdvancedSettingsPluginSetup {
|
||||||
management: ManagementSetup;
|
management: ManagementSetup;
|
||||||
|
home?: HomePublicPluginSetup;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { ComponentRegistry };
|
export { ComponentRegistry };
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"version": "kibana",
|
"version": "kibana",
|
||||||
"server": true,
|
"server": true,
|
||||||
"ui": true,
|
"ui": true,
|
||||||
"requiredPlugins": ["devTools", "home"],
|
"requiredPlugins": ["devTools"],
|
||||||
"optionalPlugins": ["usageCollection"],
|
"optionalPlugins": ["usageCollection", "home"],
|
||||||
"requiredBundles": ["esUiShared", "kibanaReact", "kibanaUtils"]
|
"requiredBundles": ["esUiShared", "kibanaReact", "kibanaUtils", "home"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,19 +28,21 @@ export class ConsoleUIPlugin implements Plugin<void, void, AppSetupUIPluginDepen
|
||||||
{ notifications, getStartServices, http }: CoreSetup,
|
{ notifications, getStartServices, http }: CoreSetup,
|
||||||
{ devTools, home, usageCollection }: AppSetupUIPluginDependencies
|
{ devTools, home, usageCollection }: AppSetupUIPluginDependencies
|
||||||
) {
|
) {
|
||||||
home.featureCatalogue.register({
|
if (home) {
|
||||||
id: 'console',
|
home.featureCatalogue.register({
|
||||||
title: i18n.translate('console.devToolsTitle', {
|
id: 'console',
|
||||||
defaultMessage: 'Console',
|
title: i18n.translate('console.devToolsTitle', {
|
||||||
}),
|
defaultMessage: 'Interact with the Elasticsearch API',
|
||||||
description: i18n.translate('console.devToolsDescription', {
|
}),
|
||||||
defaultMessage: 'Skip cURL and use this JSON interface to work with your data directly.',
|
description: i18n.translate('console.devToolsDescription', {
|
||||||
}),
|
defaultMessage: 'Skip cURL and use a JSON interface to work with your data in Console.',
|
||||||
icon: 'consoleApp',
|
}),
|
||||||
path: '/app/dev_tools#/console',
|
icon: 'consoleApp',
|
||||||
showOnHomePage: true,
|
path: '/app/dev_tools#/console',
|
||||||
category: FeatureCatalogueCategory.ADMIN,
|
showOnHomePage: false,
|
||||||
});
|
category: FeatureCatalogueCategory.ADMIN,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
devTools.register({
|
devTools.register({
|
||||||
id: 'console',
|
id: 'console',
|
||||||
|
|
|
@ -21,7 +21,7 @@ import { DevToolsSetup } from '../../../dev_tools/public';
|
||||||
import { UsageCollectionSetup } from '../../../usage_collection/public';
|
import { UsageCollectionSetup } from '../../../usage_collection/public';
|
||||||
|
|
||||||
export interface AppSetupUIPluginDependencies {
|
export interface AppSetupUIPluginDependencies {
|
||||||
home: HomePublicPluginSetup;
|
home?: HomePublicPluginSetup;
|
||||||
devTools: DevToolsSetup;
|
devTools: DevToolsSetup;
|
||||||
usageCollection?: UsageCollectionSetup;
|
usageCollection?: UsageCollectionSetup;
|
||||||
}
|
}
|
||||||
|
|
|
@ -384,7 +384,7 @@ export class DashboardPlugin
|
||||||
}),
|
}),
|
||||||
icon: 'dashboardApp',
|
icon: 'dashboardApp',
|
||||||
path: `/app/dashboards#${DashboardConstants.LANDING_PAGE_PATH}`,
|
path: `/app/dashboards#${DashboardConstants.LANDING_PAGE_PATH}`,
|
||||||
showOnHomePage: true,
|
showOnHomePage: false,
|
||||||
category: FeatureCatalogueCategory.DATA,
|
category: FeatureCatalogueCategory.DATA,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ export function registerFeature(home: HomePublicPluginSetup) {
|
||||||
}),
|
}),
|
||||||
icon: 'discoverApp',
|
icon: 'discoverApp',
|
||||||
path: '/app/discover#/',
|
path: '/app/discover#/',
|
||||||
showOnHomePage: true,
|
showOnHomePage: false,
|
||||||
category: FeatureCatalogueCategory.DATA,
|
category: FeatureCatalogueCategory.DATA,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
21
src/plugins/home/common/constants.ts
Normal file
21
src/plugins/home/common/constants.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const PLUGIN_ID = 'home';
|
||||||
|
export const HOME_APP_BASE_PATH = `/app/${PLUGIN_ID}`;
|
|
@ -35,15 +35,21 @@ export const renderApp = async (
|
||||||
) => {
|
) => {
|
||||||
const homeTitle = i18n.translate('home.breadcrumbs.homeTitle', { defaultMessage: 'Home' });
|
const homeTitle = i18n.translate('home.breadcrumbs.homeTitle', { defaultMessage: 'Home' });
|
||||||
const { featureCatalogue, chrome } = getServices();
|
const { featureCatalogue, chrome } = getServices();
|
||||||
|
const navLinks = chrome.navLinks.getAll();
|
||||||
|
|
||||||
// all the directories could be get in "start" phase of plugin after all of the legacy plugins will be moved to a NP
|
// all the directories could be get in "start" phase of plugin after all of the legacy plugins will be moved to a NP
|
||||||
const directories = featureCatalogue.get();
|
const directories = featureCatalogue.get();
|
||||||
|
|
||||||
|
// Filters solutions by available nav links
|
||||||
|
const solutions = featureCatalogue
|
||||||
|
.getSolutions()
|
||||||
|
.filter(({ id }) => navLinks.find(({ category, hidden }) => !hidden && category?.id === id));
|
||||||
|
|
||||||
chrome.setBreadcrumbs([{ text: homeTitle }]);
|
chrome.setBreadcrumbs([{ text: homeTitle }]);
|
||||||
|
|
||||||
render(
|
render(
|
||||||
<KibanaContextProvider services={{ ...coreStart }}>
|
<KibanaContextProvider services={{ ...coreStart }}>
|
||||||
<HomeApp directories={directories} />
|
<HomeApp directories={directories} solutions={solutions} />
|
||||||
</KibanaContextProvider>,
|
</KibanaContextProvider>,
|
||||||
element
|
element
|
||||||
);
|
);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -4,7 +4,7 @@ exports[`props iconType 1`] = `
|
||||||
<EuiCard
|
<EuiCard
|
||||||
betaBadgeLabel={null}
|
betaBadgeLabel={null}
|
||||||
className="homSynopsis__card homSynopsis__card--noPanel"
|
className="homSynopsis__card homSynopsis__card--noPanel"
|
||||||
data-test-subj="homeSynopsisLinkgreat tutorial"
|
data-test-subj="homeSynopsisLinktutorial"
|
||||||
description="this is a great tutorial about..."
|
description="this is a great tutorial about..."
|
||||||
href="link_to_item"
|
href="link_to_item"
|
||||||
icon={
|
icon={
|
||||||
|
@ -16,6 +16,7 @@ exports[`props iconType 1`] = `
|
||||||
}
|
}
|
||||||
layout="horizontal"
|
layout="horizontal"
|
||||||
title="Great tutorial"
|
title="Great tutorial"
|
||||||
|
titleElement="h3"
|
||||||
titleSize="xs"
|
titleSize="xs"
|
||||||
/>
|
/>
|
||||||
`;
|
`;
|
||||||
|
@ -24,7 +25,7 @@ exports[`props iconUrl 1`] = `
|
||||||
<EuiCard
|
<EuiCard
|
||||||
betaBadgeLabel={null}
|
betaBadgeLabel={null}
|
||||||
className="homSynopsis__card homSynopsis__card--noPanel"
|
className="homSynopsis__card homSynopsis__card--noPanel"
|
||||||
data-test-subj="homeSynopsisLinkgreat tutorial"
|
data-test-subj="homeSynopsisLinktutorial"
|
||||||
description="this is a great tutorial about..."
|
description="this is a great tutorial about..."
|
||||||
href="link_to_item"
|
href="link_to_item"
|
||||||
icon={
|
icon={
|
||||||
|
@ -36,6 +37,7 @@ exports[`props iconUrl 1`] = `
|
||||||
}
|
}
|
||||||
layout="horizontal"
|
layout="horizontal"
|
||||||
title="Great tutorial"
|
title="Great tutorial"
|
||||||
|
titleElement="h3"
|
||||||
titleSize="xs"
|
titleSize="xs"
|
||||||
/>
|
/>
|
||||||
`;
|
`;
|
||||||
|
@ -44,11 +46,12 @@ exports[`props isBeta 1`] = `
|
||||||
<EuiCard
|
<EuiCard
|
||||||
betaBadgeLabel="Beta"
|
betaBadgeLabel="Beta"
|
||||||
className="homSynopsis__card homSynopsis__card--noPanel"
|
className="homSynopsis__card homSynopsis__card--noPanel"
|
||||||
data-test-subj="homeSynopsisLinkgreat tutorial"
|
data-test-subj="homeSynopsisLinktutorial"
|
||||||
description="this is a great tutorial about..."
|
description="this is a great tutorial about..."
|
||||||
href="link_to_item"
|
href="link_to_item"
|
||||||
layout="horizontal"
|
layout="horizontal"
|
||||||
title="Great tutorial"
|
title="Great tutorial"
|
||||||
|
titleElement="h3"
|
||||||
titleSize="xs"
|
titleSize="xs"
|
||||||
/>
|
/>
|
||||||
`;
|
`;
|
||||||
|
@ -57,11 +60,12 @@ exports[`render 1`] = `
|
||||||
<EuiCard
|
<EuiCard
|
||||||
betaBadgeLabel={null}
|
betaBadgeLabel={null}
|
||||||
className="homSynopsis__card homSynopsis__card--noPanel"
|
className="homSynopsis__card homSynopsis__card--noPanel"
|
||||||
data-test-subj="homeSynopsisLinkgreat tutorial"
|
data-test-subj="homeSynopsisLinktutorial"
|
||||||
description="this is a great tutorial about..."
|
description="this is a great tutorial about..."
|
||||||
href="link_to_item"
|
href="link_to_item"
|
||||||
layout="horizontal"
|
layout="horizontal"
|
||||||
title="Great tutorial"
|
title="Great tutorial"
|
||||||
|
titleElement="h3"
|
||||||
titleSize="xs"
|
titleSize="xs"
|
||||||
/>
|
/>
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,63 +1,22 @@
|
||||||
.homAddData__card {
|
/*
|
||||||
border: none;
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
box-shadow: none;
|
* license agreements. See the NOTICE file distributed with
|
||||||
}
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
.homAddData__cardDivider {
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
position: relative;
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
&:after {
|
*
|
||||||
position: absolute;
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
content: '';
|
*
|
||||||
width: 1px;
|
* Unless required by applicable law or agreed to in writing,
|
||||||
right: -$euiSizeS;
|
* software distributed under the License is distributed on an
|
||||||
top: 0;
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
bottom: 0;
|
* KIND, either express or implied. See the License for the
|
||||||
background: $euiBorderColor;
|
* specific language governing permissions and limitations
|
||||||
}
|
* under the License.
|
||||||
}
|
*/
|
||||||
|
|
||||||
.homAddData__icon {
|
.homDataAdd__content .euiIcon__fillSecondary {
|
||||||
width: $euiSizeXL * 2;
|
fill: $euiColorDarkestShade;
|
||||||
height: $euiSizeXL * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.homAddData__footerItem--highlight {
|
|
||||||
background-color: tintOrShade($euiColorPrimary, 90%, 70%);
|
|
||||||
padding: $euiSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.homAddData__footerItem {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.homAddData__logo {
|
|
||||||
margin-left: $euiSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include euiBreakpoint('xs', 's') {
|
|
||||||
.homeAddData__flexGroup {
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include euiBreakpoint('xs', 's', 'm') {
|
|
||||||
.homAddDat__flexTablet {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.homAddData__cardDivider:after {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.homAddData__cardDivider {
|
|
||||||
flex-grow: 0 !important;
|
|
||||||
flex-basis: 100% !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include euiBreakpoint('l', 'xl') {
|
|
||||||
.homeAddData__flexGroup {
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,73 @@
|
||||||
@include euiBreakpoint('xs', 's', 'm') {
|
/*
|
||||||
.homHome__synopsisItem {
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
flex-basis: 100% !important;
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Local page variables
|
||||||
|
$homePageWidth: 1200px;
|
||||||
|
|
||||||
|
.homWrapper {
|
||||||
|
background-color: $euiColorEmptyShade;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: calc(100vh - #{$euiHeaderHeightCompensation});
|
||||||
|
}
|
||||||
|
|
||||||
|
.homHeader {
|
||||||
|
background-color: $euiPageBackgroundColor;
|
||||||
|
border-bottom: $euiBorderWidthThin solid $euiColorLightShade;
|
||||||
|
}
|
||||||
|
|
||||||
|
.homHeader__inner {
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: $homePageWidth;
|
||||||
|
padding: $euiSizeXL $euiSize;
|
||||||
|
|
||||||
|
.homHeader--hasSolutions & {
|
||||||
|
padding-bottom: $euiSizeXL + $euiSizeL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#homHeader__title {
|
||||||
|
@include euiBreakpoint('xs', 's') {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.homHeader__actionItem {
|
||||||
|
@include euiBreakpoint('xs', 's') {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
margin-top: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.homContent {
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: $homePageWidth;
|
||||||
|
padding: $euiSizeXL $euiSize;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.homData--expanded {
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
&,
|
||||||
|
& > * {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
margin-top: 0 !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,11 @@
|
||||||
// homChart__legend--small
|
// homChart__legend--small
|
||||||
// homChart__legend-isLoading
|
// homChart__legend-isLoading
|
||||||
|
|
||||||
@import 'add_data';
|
|
||||||
@import 'home';
|
@import 'home';
|
||||||
|
@import 'add_data';
|
||||||
|
@import 'manage_data';
|
||||||
@import 'sample_data_set_cards';
|
@import 'sample_data_set_cards';
|
||||||
|
@import 'solutions_section';
|
||||||
@import 'synopsis';
|
@import 'synopsis';
|
||||||
@import 'welcome';
|
@import 'welcome';
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.homDataManage__content .euiIcon__fillSecondary {
|
||||||
|
fill: $euiColorDarkestShade;
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.homSolutions {
|
||||||
|
margin-top: -($euiSizeXL + $euiSizeL + $euiSizeM);
|
||||||
|
}
|
||||||
|
|
||||||
|
.homSolutions__content {
|
||||||
|
min-height: $euiSize * 16;
|
||||||
|
|
||||||
|
@include euiBreakpoint('xs', 's') {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.homSolutions__group {
|
||||||
|
max-width: 50%;
|
||||||
|
|
||||||
|
@include euiBreakpoint('xs', 's') {
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.homSolutionPanel {
|
||||||
|
border-radius: $euiBorderRadius;
|
||||||
|
color: inherit;
|
||||||
|
flex: 1;
|
||||||
|
transition: all $euiAnimSpeedFast $euiAnimSlightResistance;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
@include euiSlightShadowHover;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
|
||||||
|
.euiTitle {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&,
|
||||||
|
.euiPanel {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.euiPanel {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.homSolutionPanel__header {
|
||||||
|
color: $euiColorEmptyShade;
|
||||||
|
padding: $euiSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.homSolutionPanel__icon {
|
||||||
|
background-color: $euiColorEmptyShade !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
margin: 0 auto $euiSizeS;
|
||||||
|
padding: $euiSizeS;
|
||||||
|
}
|
||||||
|
|
||||||
|
.homSolutionPanel__subtitle {
|
||||||
|
margin-top: $euiSizeXS;
|
||||||
|
}
|
||||||
|
|
||||||
|
.homSolutionPanel__content {
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
padding: $euiSize;
|
||||||
|
|
||||||
|
@include euiBreakpoint('xs', 's') {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.homSolutionPanel__header {
|
||||||
|
background-color: $euiColorPrimary;
|
||||||
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQYAAAFjCAYAAADfDKXVAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAfiSURBVHgB7d1JblRZGobh45SrhJiWGOQ6EENLSKyABTBmOcwRq2EnTKtUdInBuEln/OkMdB3HTTjiNqd5HinA3YBUSq++24UPUkq/J+jE+/fv09HRURrD27dv0+vXr1OLfksAG4QByAgDkBEGICMMQEYYgIwwABlhADLCAGSEAcgIA5ARBiAjDEBGGICMMAAZYQAywgBkhAHICAOQEQZg05/CAGy6FAYgIwzApnNhADLCAGy6EAZgkzAAGVclgIyTj0DGYgAyZ8IADP2ZLAZgw1n8IQzA0Hn8IQzA0EX8IQzAkEMJICMMwDURhcv44DDBlp4+fZrevHmTxvLq1av04cOHRDHO1h8IA1t7/PhxOjo6SjTrdP2BQwlg7ddiEAYgxGXK8/UnwgCEs+EnwgCEk+EnwgCE0+EnwgDEYcTF8AvCAJxufkEYgO+bXxAG6Nu1y5RrwgB9O7npi8IAfTu+6YvCAP3KrkasCQP06/i2bwgD9Ov0tm8IA/QpLlFe3PZNYYA+/bjrm8IA/YmTjqd3/YAwQH+O7/sBYYC+xHmFH/f9kDBAX/7Y5oeEAfqx1VoIwgD9+L7tDwoD9GHrtRCEAfoQ5xYutv1hYYD2PWgtBGGA9m11JWJIGKBtD14LQRigbf9POxAGaNedT1DeRRigTRGEb2lHwgBtetDlyU3CAO35mXY44TgkDNCWy9XrS9qTMEBb9jqEWBMGaEdchbj3TVi2IQzQhr2uQmwSBmjD5zTCIcSaMED94rzCaRqRMEDd4tLkaIcQa8IA9YpDh70vTd5EGKBOcb9CPCA12nmFIWGAOo16snGTMEB94mTjSZqQMEBdIgqjn2zcJAxQj7ircfIoBGGAOsTtzl/TTIQByhe/nXqSy5K3EQYoW0Rhp/dt3MdhAkoVdzV+Slf3LMxKGKBMcU5h1sOHIYcSUJ5FoxAsBijLLPcp3EcYoBxxOXKUd2DalzDA8uLk4sc08nsq7EMYYFnxINRkT0nuShhgOfEgVDwlOfvlyPsIAyyjmPMJNxEGmFccMsRKKOZ8wk2EAeZT7KHDJmGA6UUI4v6EYg8dNgkDTCued4i7GIu66nAfYYBpVLcShoQBxlflShgSBhhP1SthSBhgHNWvhCFhgP00sxKGhAF29OTJkyKfcxiDN2qBHb18+TIOH5qLQhAGICMMQEYYgIwwABlhADLCAGSEAcgIA5ARBiAjDEBGGICMMNCTy0ePHhX/RqwlEAZ6EQ88/e/Zs2dniXt57JrWNfl+CVMTBloW6+BTavTR6CkJA62KlfAtsRNhoDWxEr788zc7EgZaYiWMRBhogZUwMmGgdlbCBISBWlkJExIGamQlTEwYqImVMBNhoBZx5+LXxCyEgdLFXYufV6/TxGyEgZLFSojzCZ6InJkwUCIrYWHCQGmshAIIA6WwEgoiDJTASiiMMLCYw8NDK6FQ3tqNxbx79+5jEoUiCQOLef78uUOHQgkDkBEGICMMQEYYgIwwABlhADLCAGSEAcgIA5ARBiAjDEBGGNjWxYsXL/5IdOFg9fo9wd3+fr+Ey8vLf63+/k8az38PDg5m/RX1q/+G+Pf/O43j++rf/yU1yPsxcBfvl9ApYeA23lWpY8LAJisBYeAaK4G/CQMhQhAr4SRBEgauYhBRsBL4RRj6ZSVwK2Hok5XAnYShL1YCWxGGflgJbE0Y2mcl8GDC0DYrgZ0IQ5usBPYiDO35uXrFE3+zPrVIW4ShHbES4nbm4wR7EoY2WAmMShjqZiUwCWGol5XAZIShPlYCkxOGulgJzEIY6mAlMCthKJ+VwOyEoVxWAosRhjJZCSxKGMpiJVAEYSiHlUAxhGF5VgLFEYZlWQkUSRiWYSVQNGGYn5VA8YRhPlYC1RCGeVgJVEUYpmUlUCVhmI6VQLWEYXxWAtUThnFZCTRBGMZhJdAUYdiflUBzhGF3VgLNEobdnK1en5KVQKOE4eFiJXxL0DBh2F6shC///A1NE4btWAl0RRjuZiXQJWG4nZVAt4QhZyXQPWG4zkqAJAxrVgIMCMPVnYtfE/BLz2GIuxY/r16nCbim1zDESojzCZeJ3sTh4lj/389To3oLg5XQuYODA4eNW+gpDFYCbKmHMFgJ8ECth8FKgB20GgYrAfbQYhisBNhTS2GwEmAkrYTBSoAR1R4GKwEmUHMYrASYSI1hsBJgYrWFwUqAGdQSBisBZlRDGKwEmFnJYbASYCGlhsFKgAWVFgYrAQpQUhisBChECWGwEqAwS4fBSoACLRUGKwEKtkQYrAQo3JxhsBKgEnOFwUqAikwdhghBrISTBFRjyjBEDCIKVgJUZoowOJcAlRs7DM4lQAPGCsPP1etbshKgCfuGIQ4bYiH8SEAzdg1DHCrEQjhODhugOQ8NgyBAB7YNgyBAR+4LgyBAh24Lg6sM0LFhGGIRfE9XdywKAnQswrBeB2fJ4QKQrsLwMQEM/JYANggDkBEGICMMQEYYgIwwABlhADLCAGSEAcgIA5ARBiAjDEBGGICMMAAZYQAywgBkhAHICAOQEQYgIwxARhiAjDAAGWEAMg/9bdf0LX4h0XkCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACq8hdouPfUCk+KHQAAAABJRU5ErkJggg=='),
|
||||||
|
url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAWgAAAFKCAYAAAAwgcXoAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAjGSURBVHgB7d27ctRaFoDh1WBzsQ9wLkVsngHHfglSIOUdgJQiJSfmIUjhJUwGjiGaU7hmzoB7vLA1GPCt21vSlvR9Vao+5lAFbbf+EktbUgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUaxYAEzCfz/NldX9biTK+zGaz/0aLSv1FAYbg6v52I8r4e39rNdCXAoAqCTRApQQaoFICDVApgQaolEADVEqgASol0ACVEmiASgk0QKUEGqBSAg1QKYEGqJRAA1RKoAEqJdAAlRJogEp5ogowJV/3t/9EGV8DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFjELABOMZ/Po6TZrL/sDO29rATA6Vb3t/UoY29/+1f04DDO1w63Ev59uLVGoIGz5GHi9Sjja/QU6EPZvFLv5Uu07FIAUCWBBqiUQANUSqABKiXQAJUSaIBKCTRApQQaoFICDVApgQaolEADVEqgASol0ACVEmiASgl0ANRJoAEqJdAAlfJEFeAs+RSUv6OMsg8FXNw/Ue69/BMAAAAAAAAAAAAAAAAAAAAAQCdmAcBpspNn3flzL1q4EZRAA2PRhLR5vXz4683ryk+/7+j/ixO+vqiM9t6Rr78e899ffvq9za9/FWigdhnNbNVqfA/wyuHr5fgxxqMi0EDfMq4Z3ya4K4fbaMN7XgINdKGJ8OUjW/M1JxBooKSj4c3X5mhYa5bgmwYsoxlHXA0hbo1vJnCW5gRds10Jo4lOCDTws4xvRjiPjvOoeDXohUDDtB09Or4W31dTUAE/CJiWJshNjK8E1RJoGDdBHjCBhvHJCBtZjIAfHAxf7scZ46uHr/brkfCDhGFqVllcCWOL0RJoGIajs+S16Hjfnc3K/XHzefG7cp7b0N6HQEO9qhhdbG5uxosXL6KET58+xb1796IPGef79+/Ho0ePooSXL1/Gq1evok0rAdSkiXIeJVdxgm9tbS22traihJ2dnejTxsZGsffy+vXraJtAQ/+qizJ1EGjoRzNTvhGizAkEGrqVKy56OdHH8Ag0tC9vPpRBXg9RZgECDe3IEGeU82jZOmWWItBQlhEGxQg0XFyG+Lc4CLN9imJ8mGB5ebScc+W8kMTRMsUJNCzGbJnOCDScj5UYdE6g4XR5lHwjHC3TA4GGXx299FqY6Y1Aw3fNagxjDKog0CDMVEqgmbIcX+QY43pAhQSaKXLij0EQaKZEmJfU52OqShvSexFopkCYL2B7ezsePnwYJezu7kZfMsz5FJQPHz5ECe/evYu2OSHCmAkzgybQjJEwMwoCzZgIM6Mi0IxB3ifjZhxc/QejIdAMWX5+84h5PWCEBJohcuUfk+DDzdBklPOo2WeX0fMhZyjyxN/vcTBvhkkQaGq3GgcnAK3MYHIEmlo5AcjkCTQ1MmeGsANQlxxj5DhjNQCBpgr5ObwV7ssMPxBo+macASewU9AX982AMwg0XbM6A85JoOmSi01gAQJNF9xtDpYg0LTNSUBYkp2GtuRRc44znASEJQk0bXDUDAXYgSjJUTMUJNCU4qgZCrMzcVGOmqElAs1F5LK5jLPPEbTAjsUyXA0IHRBoFuVqQOiIQLOIPGr+LZic2axcKubzefSl5PtIbb+XSwFny6Plv0KcJ2lrayv29vaKbO/fv4++ZJyfPHlS7L08fvw42rYScDonAqEnAs1JnAiEngk0x8mRxh/h2YDQK4HmZ2txcGtQIw3omUBzVIbZSAMqIdAkIw2okEDjwhOolEBPW44zbgZQJYGepjwBeGt/ux5AtQR6epqrAo00oHICPS05b/4zLKGDQRDo6TBvhoER6GmwvhkGSKDHzfpmGDCBHi8nA2HgBHqcnAyEERDo8XEyEEZCoMfFI6loRZ+PqSptSO/FP4HHI++n4cpAWrGxsRGl7OzsRF/W1tbi9u3bUcLHjx9jd3c32iTQw5c/wzwZaKUGjIxAD5uVGjBiAj1c4gwjJ9DDlOOMjLOfH4yYHXx4PDMQJsJOPiwZ51sBTIJAD4c1zjAxAj0M4gwTJND1E2eYKIGum/s4w4QJdL1cug0TJ9B1EmdAoCskzsA3Al0XcQb+T6DrIc7ADwS6DuIM/EKg+yfOwLEEul/iDJxIoPsjzsCpLgV9yCsExRk4lUB3L++t4fJt4ExGHN1y4yPg3AS6O+IMLESguyHOwMLMoNuXj6kSZ2BhAt2ua+EZgsCSBLo9q3Gw1hlgKStBGy7vb3+EGT8jsL6+Hpubm1HK27dvoy8bGxvfthJ2dna+bW0S6PIyzn8dvsLg3b17N968eRMlZNDu3LkTfZjNZvHgwYN49uxZlPD06dN4/vx5tMmIo6w8YhZnoAiBLuvPEGegEIEuJ++vcSUAChHoMtxfAyhOoC8uw+xCFKA4gb6YXOt8MwBaINDLa9Y6A7RCoJdjOR3QOoFeTl7CLc5AqwR6cbli41oAtEygF2PFBtAZgT4/KzaATgn0+VixAXROoM8n4+ykINApgT5bjjVWA6BjAn269XCPDaAnAn2yHGk4KQj8Yj6fRxc8UeV4zVNRYPJ2d3dje3s7Smj7EVFn+fz5c5H3koHO70vbPDPveHlS0MUoQK+MOH7lSkGgCgL9o3wiiisFgSoI9Hc5d/49ACoh0N+5Qx1QFYE+kHNnD3wFqiLQ5s5ApaYeaHNnoFpTD3SONsydgSpNOdB5j43rAVCpqQbafTaA6k010O6zAVRvioE2dwYGYWqBtqQOGIwpBdqSOmBQphRoow1gUKYS6OthSR0wMFMIdB413wiAgZlCoI02gEEae6CNNoDBGnOgjTaAQRtzoI02gEEba6CNNoDBG2OgZ2G0AYzA/wBP5hsF50HhogAAAABJRU5ErkJggg==');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: top 0 left 0, bottom 0 right 0;
|
||||||
|
background-size: $euiSizeXL * 4, $euiSizeXL * 6;
|
||||||
|
|
||||||
|
.homSolutionPanel--enterpriseSearch & {
|
||||||
|
background-color: $euiColorSecondary;
|
||||||
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAABKCAYAAADJwhY8AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAANMSURBVHgBzZp7buIwEMYHKC1QuqsF7Up7Hs4Al+Ff4DCcAonrtPuAPjcL1B/YyA0p2JkZK580SuQm6Y+xx4+xiSqumrG+d7/z/rYx9t+WZdZ2lFhXxq4jngfkP2Ov9qquq8jnm9Zu6eBNgD6TImwsoC80ibY1NIe1sRcSVsPYHfFVN9Yy1jG2pUPbFZEUoJMP+kYHWJakAZ0AemuvrPZZJ10B8jsdHFFKWh70BSe07X1GkUoBCCHib+w1qsq1qzivLkU6JDUgTSaT7m63C4ZMCmjgaDwe4zYYMhmgB+cEyPal95IAFsA5fTGQZ4dbdcAzcO7/9wxk7bMH8AfMTvJDUsO+fG2tSfJwvp5qtdqKPgEMEYABekeBo0IEnNODgTzpI0MBfaFhnwUtAQdlBvA+X1gG0Kmw0y0J57QykE9+ASdIHo3hF29cARMO6uYDhhvFGPwfjG0E4BxPxy/gVPFR8/m8MRwOsTosPa3y9KEtigBCpmoAJwV5jGixjtp8EG3xD8noOASKjiT2V6+Jr5YLFo2hDuvkDfEErqa7EZXx4naxWKyIr9b+e6QkU0U/iBcw+2jWnM08E09NtMMqA0JNNUC0ReInlRraE9bodXBOzaoD1rQBuVku9SpmZ7eSL9wjVa864LbqgOpVzJ4bagNyv7/RBozZgymSOuAN8bRTA7RrFM4+DJRpepBbvZAqIDf3jQmrThXbxCS3i5FdduYksXOAjUp5QJt75npvK75whwwclopd4uvV3YgB2m7lG8nouK0rAojkEcnlZTZ+plUCsDEajfom9SYBB31InXA/is64h+8sl0vKsowGgwExBO/99QvKDkXISHQpFxCz2Wx/nU6nVFIniacyHkTOpGevJ2J48sR7UKgHnceCRoiSnvxVVOj2P6C6ZyjHVKljwb7a54KDKtKT2MgpPDECD/ZJSYGedEdaCqW+437BkzgcdG/zOIVKciTgDOTawL2dezfVmYUiyHV+V6lIyQAhDxJwjyHvoPv4SWmFgAiCg1JnFqLgIO6qK1SIVowS0afjUgCin/tNJZOZ2oCIUlRr6aOlWoDwFjZz2CczpQHhKXjsYv8WKilAeAwBgL0R0ZPCHECAvFirzCFb/5hyknPV7zL4DLH0CVGgAAAAAElFTkSuQmCC'),
|
||||||
|
url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAA+CAYAAACbQR1vAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACBSURBVHgB7dpBDcAwDMVQdyzGH9xojEQjtbIfBEu5fGUx62WPjyEPcgVArgDIFQC5AiBXAOQKgFwBkCsAcgVATh9gsW+4vFIngFwBkCsAcgVArgDIFQC5AiBXAORahJjVm9zpCoBcAZArAHIFQK4AyBUAuQIgVwDkCoBcAZDTB/gBLrgCk8OhuvYAAAAASUVORK5CYII=');
|
||||||
|
background-position: top $euiSizeS left 0, bottom $euiSizeS right $euiSizeS;
|
||||||
|
background-size: $euiSize * 1.25, $euiSizeXL;
|
||||||
|
}
|
||||||
|
|
||||||
|
.homSolutionPanel--observability & {
|
||||||
|
background-color: $euiColorAccent;
|
||||||
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAADNSURBVHgB7duxCcIAEEDR08IFrGyz/0pZwVYEIcYF/FWKwHtwXP/hyrvMQbZtu+3rPid3Hf4SKAgUBAoCBYGCQEGgIFAQKAgUBAoCBYGCQEGgIFAQKAgUBAoCBYGCQEGgIFAQKAgUBAoCBYGCQEGgIFAQKAgUBAoCBYGCQEGgIFAQKAgUBAoCBYGCQEGgcJmDnt6WZfms6/qak/sFeswx3vs85+ScWBAoCBQECgIFgYJAQaAgUBAoCBQECgIFgYJAQaAgUBAoCBQECgKFLx4KCqcIFEJnAAAAAElFTkSuQmCC');
|
||||||
|
background-position: top $euiSizeS right $euiSizeS;
|
||||||
|
background-size: $euiSizeL * 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.homSolutionPanel--securitySolution & {
|
||||||
|
background-color: $euiColorDarkestShade;
|
||||||
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGIAAABiCAYAAACrpQYOAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAKRSURBVHgB7d3tSgMxEIXhMeqPQoWC9f4vte5Z3dLvTbKZzCQ5LyxqKwg+tNjdUxQR+RJmXpiOvRDDvPD/kRjGhYvPgbETZlK4+fogxDApPLiNGAaFJ7cD40NYtcKL+76FGNUKK/cRo1Ih4n5gvAtTbQ1i+R5iKBcDgYBADMViIRAxFEuBQMRQKhUCEUOhHAi0YLwJK1IuBCJGwbZAoE8hRpG2QqAFg22oBAQCxkFYdqUgEE6dEyOzkhCIGJmVhkDA4PXvxDQgEMcIiWlBIGIkpAmBiBGZNgQiRkQ1IBAxVqoFgThge1FNCMTN1JNqQyBiPMgCAnHAdpMVBOJm6iJLCA7YLrKEWH4+r3+LPYQIMeY8QKDhlyFeINDQGJ4g0LAY3iDQkBgeIdBwmymvEGgoDM8QaJgBm3cINMSArQUI1P2ArRUI1PVmqiUI1C1GaxCoywFbixCouzFCqxCIyxBPnU6nLjBafkQs7YExHdJyPUCg+WmqZYxeIBAwmv3TticItJseFYcWHxm9QaD5RV9rGD1CIGAcJ4xmztr2CoHms7atYPQMgc4Y3p+qeodAwPiZjnfPGCNAoPMgwSvGKBDINcZIEMgtxmgQyCXGiBDIHcaoEAgYx+n48IAxMgQ6v1nGGmN0COQCgxB/4feAF307KwxCXDe/9dgCgxD3mWAQ4nHAqHrplRDPq3odnBCvq4ZBiPWqYBAiLnUMQsSnikGItObtlAYGIdJTmesQIq/iGITIr+h2ihDbKradIsT2imynCFGmzdspQpRr03VwQpQtG4MQ5cvCIIROyRiE0CsJgxC6RW+nCKFf1FyHEHVaxSBEvV5upwhRv4dzHULYdIdBCLuutlOEsO18HZz/u8E+YMgvrbKfmp8y7IEAAAAASUVORK5CYII=');
|
||||||
|
background-position: top $euiSizeS left $euiSizeS;
|
||||||
|
background-size: $euiSizeL * 2;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,10 @@
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.homSynopsis__cardTitle {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
// SASSTODO: Fix in EUI
|
// SASSTODO: Fix in EUI
|
||||||
.euiCard__content {
|
.euiCard__content {
|
||||||
padding-top: 0 !important;
|
padding-top: 0 !important;
|
||||||
|
|
|
@ -1,320 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
|
||||||
* license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright
|
|
||||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
|
||||||
* the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
* not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
|
||||||
import { getServices } from '../kibana_services';
|
|
||||||
|
|
||||||
import {
|
|
||||||
EuiButton,
|
|
||||||
EuiLink,
|
|
||||||
EuiPanel,
|
|
||||||
EuiTitle,
|
|
||||||
EuiSpacer,
|
|
||||||
EuiFlexGroup,
|
|
||||||
EuiFlexItem,
|
|
||||||
EuiText,
|
|
||||||
EuiCard,
|
|
||||||
EuiIcon,
|
|
||||||
EuiHorizontalRule,
|
|
||||||
EuiFlexGrid,
|
|
||||||
} from '@elastic/eui';
|
|
||||||
|
|
||||||
const AddDataUi = ({ apmUiEnabled, isNewKibanaInstance, intl, mlEnabled }) => {
|
|
||||||
const basePath = getServices().getBasePath();
|
|
||||||
|
|
||||||
const renderCards = () => {
|
|
||||||
const apmData = {
|
|
||||||
title: intl.formatMessage({
|
|
||||||
id: 'home.addData.apm.nameTitle',
|
|
||||||
defaultMessage: 'APM',
|
|
||||||
}),
|
|
||||||
description: intl.formatMessage({
|
|
||||||
id: 'home.addData.apm.nameDescription',
|
|
||||||
defaultMessage:
|
|
||||||
'APM automatically collects in-depth performance metrics and errors from inside your applications.',
|
|
||||||
}),
|
|
||||||
ariaDescribedby: 'aria-describedby.addAmpButtonLabel',
|
|
||||||
};
|
|
||||||
const loggingData = {
|
|
||||||
title: intl.formatMessage({
|
|
||||||
id: 'home.addData.logging.nameTitle',
|
|
||||||
defaultMessage: 'Logs',
|
|
||||||
}),
|
|
||||||
description: intl.formatMessage({
|
|
||||||
id: 'home.addData.logging.nameDescription',
|
|
||||||
defaultMessage:
|
|
||||||
'Ingest logs from popular data sources and easily visualize in preconfigured dashboards.',
|
|
||||||
}),
|
|
||||||
ariaDescribedby: 'aria-describedby.addLogDataButtonLabel',
|
|
||||||
};
|
|
||||||
const metricsData = {
|
|
||||||
title: intl.formatMessage({
|
|
||||||
id: 'home.addData.metrics.nameTitle',
|
|
||||||
defaultMessage: 'Metrics',
|
|
||||||
}),
|
|
||||||
description: intl.formatMessage({
|
|
||||||
id: 'home.addData.metrics.nameDescription',
|
|
||||||
defaultMessage:
|
|
||||||
'Collect metrics from the operating system and services running on your servers.',
|
|
||||||
}),
|
|
||||||
ariaDescribedby: 'aria-describedby.addMetricsButtonLabel',
|
|
||||||
};
|
|
||||||
const siemData = {
|
|
||||||
title: intl.formatMessage({
|
|
||||||
id: 'home.addData.securitySolution.nameTitle',
|
|
||||||
defaultMessage: 'SIEM + Endpoint Security',
|
|
||||||
}),
|
|
||||||
description: intl.formatMessage({
|
|
||||||
id: 'home.addData.securitySolution.nameDescription',
|
|
||||||
defaultMessage:
|
|
||||||
'Protect hosts, analyze security information and events, hunt threats, automate detections, and create cases.',
|
|
||||||
}),
|
|
||||||
ariaDescribedby: 'aria-describedby.addSiemButtonLabel',
|
|
||||||
};
|
|
||||||
|
|
||||||
const getApmCard = () => (
|
|
||||||
<EuiFlexItem grow={1} className="homAddData__flexItem">
|
|
||||||
<EuiCard
|
|
||||||
textAlign="left"
|
|
||||||
className="homAddData__card"
|
|
||||||
titleSize="xs"
|
|
||||||
title={apmData.title}
|
|
||||||
description={<span id={apmData.ariaDescribedby}>{apmData.description}</span>}
|
|
||||||
footer={
|
|
||||||
<EuiButton
|
|
||||||
className="homAddData__button"
|
|
||||||
href="#/tutorial/apm"
|
|
||||||
aria-describedby={apmData.ariaDescribedby}
|
|
||||||
>
|
|
||||||
<FormattedMessage id="home.addData.apm.addApmButtonLabel" defaultMessage="Add APM" />
|
|
||||||
</EuiButton>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</EuiFlexItem>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<EuiFlexGroup
|
|
||||||
className="homeAddData__flexGroup homAddData__flexTablet"
|
|
||||||
wrap={apmUiEnabled}
|
|
||||||
gutterSize="l"
|
|
||||||
justifyContent="spaceAround"
|
|
||||||
responsive={false}
|
|
||||||
>
|
|
||||||
<EuiFlexItem className="homAddData__cardDivider homAddData__flexItem" grow={3}>
|
|
||||||
<EuiSpacer size="m" />
|
|
||||||
<EuiFlexGroup alignItems="center" gutterSize="m" responsive={false}>
|
|
||||||
<EuiFlexItem grow={false}>
|
|
||||||
<EuiIcon size="xl" type="logoObservability" className="homAddData__logo" />
|
|
||||||
</EuiFlexItem>
|
|
||||||
<EuiFlexItem grow={false}>
|
|
||||||
<EuiTitle size="s">
|
|
||||||
<h2>
|
|
||||||
<FormattedMessage
|
|
||||||
id="home.addData.title.observability"
|
|
||||||
defaultMessage="Observability"
|
|
||||||
/>
|
|
||||||
</h2>
|
|
||||||
</EuiTitle>
|
|
||||||
</EuiFlexItem>
|
|
||||||
</EuiFlexGroup>
|
|
||||||
<EuiSpacer />
|
|
||||||
<EuiFlexGroup
|
|
||||||
className="homeAddData__flexGroup"
|
|
||||||
wrap={apmUiEnabled}
|
|
||||||
gutterSize="l"
|
|
||||||
justifyContent="spaceAround"
|
|
||||||
responsive={false}
|
|
||||||
>
|
|
||||||
{apmUiEnabled !== false && getApmCard()}
|
|
||||||
|
|
||||||
<EuiFlexItem grow={1} className="homAddData__flexItem">
|
|
||||||
<EuiCard
|
|
||||||
textAlign="left"
|
|
||||||
className="homAddData__card"
|
|
||||||
title={loggingData.title}
|
|
||||||
titleSize="xs"
|
|
||||||
description={
|
|
||||||
<span id={loggingData.ariaDescribedby}>{loggingData.description}</span>
|
|
||||||
}
|
|
||||||
footer={
|
|
||||||
<EuiButton
|
|
||||||
className="homAddData__button"
|
|
||||||
data-test-subj="logsData"
|
|
||||||
href="#/tutorial_directory/logging"
|
|
||||||
aria-describedby={loggingData.ariaDescribedby}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id="home.addData.logging.addLogDataButtonLabel"
|
|
||||||
defaultMessage="Add log data"
|
|
||||||
/>
|
|
||||||
</EuiButton>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</EuiFlexItem>
|
|
||||||
|
|
||||||
<EuiFlexItem grow={1} className="homAddData__flexItem">
|
|
||||||
<EuiCard
|
|
||||||
textAlign="left"
|
|
||||||
className="homAddData__card"
|
|
||||||
title={metricsData.title}
|
|
||||||
titleSize="xs"
|
|
||||||
description={
|
|
||||||
<span id={metricsData.ariaDescribedby}>{metricsData.description}</span>
|
|
||||||
}
|
|
||||||
footer={
|
|
||||||
<EuiButton
|
|
||||||
className="homAddData__button"
|
|
||||||
href="#/tutorial_directory/metrics"
|
|
||||||
aria-describedby={metricsData.ariaDescribedby}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id="home.addData.metrics.addMetricsDataButtonLabel"
|
|
||||||
defaultMessage="Add metric data"
|
|
||||||
/>
|
|
||||||
</EuiButton>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</EuiFlexItem>
|
|
||||||
</EuiFlexGroup>
|
|
||||||
</EuiFlexItem>
|
|
||||||
|
|
||||||
<EuiFlexItem grow={1} className="homAddData__flexItem">
|
|
||||||
<EuiFlexGroup alignItems="center" gutterSize="m" responsive={false}>
|
|
||||||
<EuiFlexItem grow={false}>
|
|
||||||
<EuiIcon size="xl" type="logoSecurity" className="homAddData__logo" />
|
|
||||||
</EuiFlexItem>
|
|
||||||
<EuiFlexItem grow={false}>
|
|
||||||
<EuiTitle size="s">
|
|
||||||
<h2>
|
|
||||||
<FormattedMessage id="home.addData.title.security" defaultMessage="Security" />
|
|
||||||
</h2>
|
|
||||||
</EuiTitle>
|
|
||||||
</EuiFlexItem>
|
|
||||||
</EuiFlexGroup>
|
|
||||||
<EuiSpacer size="s" />
|
|
||||||
<EuiCard
|
|
||||||
textAlign="left"
|
|
||||||
titleSize="xs"
|
|
||||||
className="homAddData__card"
|
|
||||||
title={siemData.title}
|
|
||||||
description={<span id={siemData.ariaDescribedby}>{siemData.description}</span>}
|
|
||||||
footer={
|
|
||||||
<EuiButton
|
|
||||||
className="homAddData__button"
|
|
||||||
href="#/tutorial_directory/security"
|
|
||||||
aria-describedby={siemData.ariaDescribedby}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id="home.addData.securitySolution.addSecurityEventsButtonLabel"
|
|
||||||
defaultMessage="Add events"
|
|
||||||
/>
|
|
||||||
</EuiButton>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</EuiFlexItem>
|
|
||||||
</EuiFlexGroup>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const footerItemClasses = classNames('homAddData__footerItem', {
|
|
||||||
'homAddData__footerItem--highlight': isNewKibanaInstance,
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<EuiPanel paddingSize="l">
|
|
||||||
{renderCards()}
|
|
||||||
|
|
||||||
<EuiHorizontalRule />
|
|
||||||
|
|
||||||
<EuiFlexGrid columns={mlEnabled !== false ? 3 : 2}>
|
|
||||||
<EuiFlexItem className={footerItemClasses}>
|
|
||||||
<EuiText size="s">
|
|
||||||
<strong style={{ height: 38 }}>
|
|
||||||
<FormattedMessage
|
|
||||||
id="home.addData.sampleDataTitle"
|
|
||||||
defaultMessage="Add sample data"
|
|
||||||
/>
|
|
||||||
</strong>
|
|
||||||
<EuiLink
|
|
||||||
style={{ display: 'block', textAlign: 'center' }}
|
|
||||||
href="#/tutorial_directory/sampleData"
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id="home.addData.sampleDataLink"
|
|
||||||
defaultMessage="Load a data set and a Kibana dashboard"
|
|
||||||
/>
|
|
||||||
</EuiLink>
|
|
||||||
</EuiText>
|
|
||||||
</EuiFlexItem>
|
|
||||||
{mlEnabled !== false ? (
|
|
||||||
<EuiFlexItem className={footerItemClasses}>
|
|
||||||
<EuiText size="s">
|
|
||||||
<strong style={{ height: 38 }}>
|
|
||||||
<FormattedMessage
|
|
||||||
id="home.addData.uploadFileTitle"
|
|
||||||
defaultMessage="Upload data from log file"
|
|
||||||
/>
|
|
||||||
</strong>
|
|
||||||
<EuiLink
|
|
||||||
style={{ display: 'block', textAlign: 'center' }}
|
|
||||||
href={`${basePath}/app/ml#/filedatavisualizer`}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id="home.addData.uploadFileLink"
|
|
||||||
defaultMessage="Import a CSV, NDJSON, or log file"
|
|
||||||
/>
|
|
||||||
</EuiLink>
|
|
||||||
</EuiText>
|
|
||||||
</EuiFlexItem>
|
|
||||||
) : null}
|
|
||||||
<EuiFlexItem className={footerItemClasses}>
|
|
||||||
<EuiText size="s">
|
|
||||||
<strong style={{ height: 38 }}>
|
|
||||||
<FormattedMessage
|
|
||||||
id="home.addData.yourDataTitle"
|
|
||||||
defaultMessage="Use Elasticsearch data"
|
|
||||||
/>
|
|
||||||
</strong>
|
|
||||||
<EuiLink
|
|
||||||
style={{ display: 'block', textAlign: 'center' }}
|
|
||||||
href={`${basePath}/app/management/kibana/indexPatterns`}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id="home.addData.yourDataLink"
|
|
||||||
defaultMessage="Connect to your Elasticsearch index"
|
|
||||||
/>
|
|
||||||
</EuiLink>
|
|
||||||
</EuiText>
|
|
||||||
</EuiFlexItem>
|
|
||||||
</EuiFlexGrid>
|
|
||||||
</EuiPanel>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
AddDataUi.propTypes = {
|
|
||||||
apmUiEnabled: PropTypes.bool.isRequired,
|
|
||||||
mlEnabled: PropTypes.bool.isRequired,
|
|
||||||
isNewKibanaInstance: PropTypes.bool.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const AddData = injectI18n(AddDataUi);
|
|
|
@ -1,68 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
|
||||||
* license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright
|
|
||||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
|
||||||
* the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
* not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import { AddData } from './add_data';
|
|
||||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
|
||||||
import { getServices } from '../kibana_services';
|
|
||||||
|
|
||||||
jest.mock('../kibana_services', () => {
|
|
||||||
const mock = {
|
|
||||||
getBasePath: jest.fn(() => 'path'),
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
getServices: () => mock,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
jest.clearAllMocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('render', () => {
|
|
||||||
const component = shallowWithIntl(
|
|
||||||
<AddData.WrappedComponent apmUiEnabled={false} mlEnabled={false} isNewKibanaInstance={false} />
|
|
||||||
);
|
|
||||||
expect(component).toMatchSnapshot(); // eslint-disable-line
|
|
||||||
expect(getServices().getBasePath).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('mlEnabled', () => {
|
|
||||||
const component = shallowWithIntl(
|
|
||||||
<AddData.WrappedComponent apmUiEnabled={true} mlEnabled={true} isNewKibanaInstance={false} />
|
|
||||||
);
|
|
||||||
expect(component).toMatchSnapshot(); // eslint-disable-line
|
|
||||||
expect(getServices().getBasePath).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('apmUiEnabled', () => {
|
|
||||||
const component = shallowWithIntl(
|
|
||||||
<AddData.WrappedComponent apmUiEnabled={true} mlEnabled={false} isNewKibanaInstance={false} />
|
|
||||||
);
|
|
||||||
expect(component).toMatchSnapshot(); // eslint-disable-line
|
|
||||||
expect(getServices().getBasePath).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('isNewKibanaInstance', () => {
|
|
||||||
const component = shallowWithIntl(
|
|
||||||
<AddData.WrappedComponent apmUiEnabled={false} mlEnabled={false} isNewKibanaInstance={true} />
|
|
||||||
);
|
|
||||||
expect(component).toMatchSnapshot(); // eslint-disable-line
|
|
||||||
expect(getServices().getBasePath).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
96
src/plugins/home/public/application/components/add_data/__snapshots__/add_data.test.tsx.snap
generated
Normal file
96
src/plugins/home/public/application/components/add_data/__snapshots__/add_data.test.tsx.snap
generated
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`AddData render 1`] = `
|
||||||
|
<section
|
||||||
|
aria-labelledby="homDataAdd__title"
|
||||||
|
className="homDataAdd"
|
||||||
|
>
|
||||||
|
<EuiFlexGroup
|
||||||
|
alignItems="center"
|
||||||
|
responsive={false}
|
||||||
|
>
|
||||||
|
<EuiFlexItem
|
||||||
|
grow={1}
|
||||||
|
>
|
||||||
|
<EuiTitle
|
||||||
|
size="s"
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
id="homDataAdd__title"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Ingest your data"
|
||||||
|
id="home.addData.sectionTitle"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</h2>
|
||||||
|
</EuiTitle>
|
||||||
|
</EuiFlexItem>
|
||||||
|
<EuiFlexItem
|
||||||
|
grow={false}
|
||||||
|
>
|
||||||
|
<EuiButtonEmpty
|
||||||
|
flush="right"
|
||||||
|
href="#/tutorial_directory/sampleData"
|
||||||
|
iconType="visTable"
|
||||||
|
size="xs"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Try our sample data"
|
||||||
|
id="home.addData.sampleDataButtonLabel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</EuiButtonEmpty>
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
<EuiSpacer
|
||||||
|
size="m"
|
||||||
|
/>
|
||||||
|
<EuiFlexGroup
|
||||||
|
className="homDataAdd__content"
|
||||||
|
>
|
||||||
|
<EuiFlexItem
|
||||||
|
key="home_tutorial_directory"
|
||||||
|
>
|
||||||
|
<Synopsis
|
||||||
|
description="Ingest data from popular apps and services."
|
||||||
|
iconType="indexOpen"
|
||||||
|
id="home_tutorial_directory"
|
||||||
|
isBeta={false}
|
||||||
|
onClick={[Function]}
|
||||||
|
title="Ingest data"
|
||||||
|
url="/app/home#/tutorial_directory"
|
||||||
|
wrapInPanel={true}
|
||||||
|
/>
|
||||||
|
</EuiFlexItem>
|
||||||
|
<EuiFlexItem
|
||||||
|
key="ingestManager"
|
||||||
|
>
|
||||||
|
<Synopsis
|
||||||
|
description="Add and manage your fleet of Elastic Agents and integrations."
|
||||||
|
iconType="indexManagementApp"
|
||||||
|
id="ingestManager"
|
||||||
|
isBeta={false}
|
||||||
|
onClick={[Function]}
|
||||||
|
title="Add Elastic Agent"
|
||||||
|
url="/app/ingestManager"
|
||||||
|
wrapInPanel={true}
|
||||||
|
/>
|
||||||
|
</EuiFlexItem>
|
||||||
|
<EuiFlexItem
|
||||||
|
key="ml_file_data_visualizer"
|
||||||
|
>
|
||||||
|
<Synopsis
|
||||||
|
description="Import your own CSV, NDJSON, or log file"
|
||||||
|
iconType="document"
|
||||||
|
id="ml_file_data_visualizer"
|
||||||
|
isBeta={false}
|
||||||
|
onClick={[Function]}
|
||||||
|
title="Upload a file"
|
||||||
|
url="/app/ml#/filedatavisualizer"
|
||||||
|
wrapInPanel={true}
|
||||||
|
/>
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</section>
|
||||||
|
`;
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { AddData } from './add_data';
|
||||||
|
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||||
|
|
||||||
|
jest.mock('../app_navigation_handler', () => {
|
||||||
|
return {
|
||||||
|
createAppNavigationHandler: jest.fn(() => () => {}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
const addBasePathMock = jest.fn((path: string) => (path ? path : 'path'));
|
||||||
|
|
||||||
|
const mockFeatures = [
|
||||||
|
{
|
||||||
|
category: 'data',
|
||||||
|
description: 'Ingest data from popular apps and services.',
|
||||||
|
homePageSection: 'add_data',
|
||||||
|
icon: 'indexOpen',
|
||||||
|
id: 'home_tutorial_directory',
|
||||||
|
order: 500,
|
||||||
|
path: '/app/home#/tutorial_directory',
|
||||||
|
title: 'Ingest data',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: 'admin',
|
||||||
|
description: 'Add and manage your fleet of Elastic Agents and integrations.',
|
||||||
|
homePageSection: 'add_data',
|
||||||
|
icon: 'indexManagementApp',
|
||||||
|
id: 'ingestManager',
|
||||||
|
order: 510,
|
||||||
|
path: '/app/ingestManager',
|
||||||
|
title: 'Add Elastic Agent',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: 'data',
|
||||||
|
description: 'Import your own CSV, NDJSON, or log file',
|
||||||
|
homePageSection: 'add_data',
|
||||||
|
icon: 'document',
|
||||||
|
id: 'ml_file_data_visualizer',
|
||||||
|
order: 520,
|
||||||
|
path: '/app/ml#/filedatavisualizer',
|
||||||
|
title: 'Upload a file',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
describe('AddData', () => {
|
||||||
|
test('render', () => {
|
||||||
|
const component = shallowWithIntl(
|
||||||
|
<AddData addBasePath={addBasePathMock} features={mockFeatures} />
|
||||||
|
);
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { FC } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle } from '@elastic/eui';
|
||||||
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
// @ts-expect-error untyped service
|
||||||
|
import { FeatureCatalogueEntry } from '../../services';
|
||||||
|
import { createAppNavigationHandler } from '../app_navigation_handler';
|
||||||
|
// @ts-expect-error untyped component
|
||||||
|
import { Synopsis } from '../synopsis';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
addBasePath: (path: string) => string;
|
||||||
|
features: FeatureCatalogueEntry[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AddData: FC<Props> = ({ addBasePath, features }) => (
|
||||||
|
<section className="homDataAdd" aria-labelledby="homDataAdd__title">
|
||||||
|
<EuiFlexGroup alignItems="center" responsive={false}>
|
||||||
|
<EuiFlexItem grow={1}>
|
||||||
|
<EuiTitle size="s">
|
||||||
|
<h2 id="homDataAdd__title">
|
||||||
|
<FormattedMessage id="home.addData.sectionTitle" defaultMessage="Ingest your data" />
|
||||||
|
</h2>
|
||||||
|
</EuiTitle>
|
||||||
|
</EuiFlexItem>
|
||||||
|
|
||||||
|
<EuiFlexItem grow={false}>
|
||||||
|
<EuiButtonEmpty
|
||||||
|
iconType="visTable"
|
||||||
|
href="#/tutorial_directory/sampleData"
|
||||||
|
size="xs"
|
||||||
|
flush="right"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id="home.addData.sampleDataButtonLabel"
|
||||||
|
defaultMessage="Try our sample data"
|
||||||
|
/>
|
||||||
|
</EuiButtonEmpty>
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
|
||||||
|
<EuiSpacer size="m" />
|
||||||
|
|
||||||
|
<EuiFlexGroup className="homDataAdd__content">
|
||||||
|
{features.map((feature) => (
|
||||||
|
<EuiFlexItem key={feature.id}>
|
||||||
|
<Synopsis
|
||||||
|
id={feature.id}
|
||||||
|
onClick={createAppNavigationHandler(feature.path)}
|
||||||
|
description={feature.description}
|
||||||
|
iconType={feature.icon}
|
||||||
|
title={feature.title}
|
||||||
|
url={addBasePath(feature.path)}
|
||||||
|
wrapInPanel
|
||||||
|
/>
|
||||||
|
</EuiFlexItem>
|
||||||
|
))}
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
|
||||||
|
AddData.propTypes = {
|
||||||
|
addBasePath: PropTypes.func.isRequired,
|
||||||
|
features: PropTypes.arrayOf(
|
||||||
|
PropTypes.shape({
|
||||||
|
id: PropTypes.string.isRequired,
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
|
description: PropTypes.string.isRequired,
|
||||||
|
icon: PropTypes.string.isRequired,
|
||||||
|
path: PropTypes.string.isRequired,
|
||||||
|
showOnHomePage: PropTypes.bool.isRequired,
|
||||||
|
category: PropTypes.string.isRequired,
|
||||||
|
order: PropTypes.number,
|
||||||
|
})
|
||||||
|
),
|
||||||
|
};
|
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './add_data';
|
|
@ -17,6 +17,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { MouseEvent } from 'react';
|
||||||
import { getServices } from '../kibana_services';
|
import { getServices } from '../kibana_services';
|
||||||
|
|
||||||
export const createAppNavigationHandler = (targetUrl: string) => (event: MouseEvent) => {
|
export const createAppNavigationHandler = (targetUrl: string) => (event: MouseEvent) => {
|
||||||
|
|
|
@ -115,6 +115,7 @@ export class FeatureDirectory extends React.Component {
|
||||||
return (
|
return (
|
||||||
<EuiFlexItem key={directory.id}>
|
<EuiFlexItem key={directory.id}>
|
||||||
<Synopsis
|
<Synopsis
|
||||||
|
id={directory.id}
|
||||||
onClick={createAppNavigationHandler(directory.path)}
|
onClick={createAppNavigationHandler(directory.path)}
|
||||||
description={directory.description}
|
description={directory.description}
|
||||||
iconType={directory.icon}
|
iconType={directory.icon}
|
||||||
|
@ -157,6 +158,7 @@ FeatureDirectory.propTypes = {
|
||||||
path: PropTypes.string.isRequired,
|
path: PropTypes.string.isRequired,
|
||||||
showOnHomePage: PropTypes.bool.isRequired,
|
showOnHomePage: PropTypes.bool.isRequired,
|
||||||
category: PropTypes.string.isRequired,
|
category: PropTypes.string.isRequired,
|
||||||
|
order: PropTypes.number,
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,29 +19,22 @@
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Synopsis } from './synopsis';
|
|
||||||
import { AddData } from './add_data';
|
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EuiButton,
|
EuiButtonEmpty,
|
||||||
EuiPage,
|
|
||||||
EuiPanel,
|
|
||||||
EuiTitle,
|
EuiTitle,
|
||||||
EuiSpacer,
|
|
||||||
EuiFlexGroup,
|
EuiFlexGroup,
|
||||||
EuiFlexItem,
|
EuiFlexItem,
|
||||||
EuiFlexGrid,
|
EuiHorizontalRule,
|
||||||
EuiText,
|
|
||||||
EuiPageBody,
|
|
||||||
EuiScreenReaderOnly,
|
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
import { Welcome } from './welcome';
|
|
||||||
import { getServices } from '../kibana_services';
|
|
||||||
import { FeatureCatalogueCategory } from '../../services';
|
import { FeatureCatalogueCategory } from '../../services';
|
||||||
|
import { getServices } from '../kibana_services';
|
||||||
|
import { AddData } from './add_data';
|
||||||
import { createAppNavigationHandler } from './app_navigation_handler';
|
import { createAppNavigationHandler } from './app_navigation_handler';
|
||||||
|
import { ManageData } from './manage_data';
|
||||||
|
import { SolutionsSection } from './solutions_section';
|
||||||
|
import { Welcome } from './welcome';
|
||||||
|
|
||||||
const KEY_ENABLE_WELCOME = 'home:welcome:show';
|
const KEY_ENABLE_WELCOME = 'home:welcome:show';
|
||||||
|
|
||||||
|
@ -53,6 +46,10 @@ export class Home extends Component {
|
||||||
getServices().homeConfig.disableWelcomeScreen ||
|
getServices().homeConfig.disableWelcomeScreen ||
|
||||||
props.localStorage.getItem(KEY_ENABLE_WELCOME) === 'false'
|
props.localStorage.getItem(KEY_ENABLE_WELCOME) === 'false'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const body = document.querySelector('body');
|
||||||
|
body.classList.add('isHomPage');
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
// If welcome is enabled, we wait for loading to complete
|
// If welcome is enabled, we wait for loading to complete
|
||||||
// before rendering. This prevents an annoying flickering
|
// before rendering. This prevents an annoying flickering
|
||||||
|
@ -116,105 +113,144 @@ export class Home extends Component {
|
||||||
this._isMounted && this.setState({ isWelcomeEnabled: false });
|
this._isMounted && this.setState({ isWelcomeEnabled: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
renderDirectories = (category) => {
|
findDirectoryById = (id) => this.props.directories.find((directory) => directory.id === id);
|
||||||
const { addBasePath, directories } = this.props;
|
|
||||||
return directories
|
getFeaturesByCategory = (category) =>
|
||||||
.filter((directory) => {
|
this.props.directories
|
||||||
return directory.showOnHomePage && directory.category === category;
|
.filter((directory) => directory.showOnHomePage && directory.category === category)
|
||||||
})
|
.sort((directoryA, directoryB) => directoryA.order - directoryB.order);
|
||||||
.map((directory) => {
|
|
||||||
return (
|
|
||||||
<EuiFlexItem className="homHome__synopsisItem" key={directory.id}>
|
|
||||||
<Synopsis
|
|
||||||
onClick={createAppNavigationHandler(directory.path)}
|
|
||||||
description={directory.description}
|
|
||||||
iconType={directory.icon}
|
|
||||||
title={directory.title}
|
|
||||||
url={addBasePath(directory.path)}
|
|
||||||
/>
|
|
||||||
</EuiFlexItem>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
renderNormal() {
|
renderNormal() {
|
||||||
const { apmUiEnabled, mlEnabled } = this.props;
|
const { addBasePath, solutions } = this.props;
|
||||||
|
|
||||||
|
const devTools = this.findDirectoryById('console');
|
||||||
|
const stackManagement = this.findDirectoryById('stack-management');
|
||||||
|
const advancedSettings = this.findDirectoryById('advanced_settings');
|
||||||
|
|
||||||
|
const addDataFeatures = this.getFeaturesByCategory(FeatureCatalogueCategory.DATA);
|
||||||
|
const manageDataFeatures = this.getFeaturesByCategory(FeatureCatalogueCategory.ADMIN);
|
||||||
|
|
||||||
|
// Show card for console if none of the manage data plugins are available, most likely in OSS
|
||||||
|
if (manageDataFeatures.length < 1 && devTools) {
|
||||||
|
manageDataFeatures.push(devTools);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EuiPage restrictWidth={1200} data-test-subj="homeApp">
|
<main aria-labelledby="homHeader__title" className="homWrapper" data-test-subj="homeApp">
|
||||||
<EuiPageBody className="eui-displayBlock">
|
<header
|
||||||
<EuiScreenReaderOnly>
|
className={`homHeader ${
|
||||||
<h1>
|
solutions.length ? 'homHeader--hasSolutions' : 'homHeader--noSolutions'
|
||||||
<FormattedMessage id="home.welcomeHomePageHeader" defaultMessage="Kibana home" />
|
}`}
|
||||||
</h1>
|
>
|
||||||
</EuiScreenReaderOnly>
|
<div className="homHeader__inner">
|
||||||
|
<EuiFlexGroup>
|
||||||
<AddData
|
<EuiFlexItem>
|
||||||
apmUiEnabled={apmUiEnabled}
|
<EuiTitle size="m">
|
||||||
mlEnabled={mlEnabled}
|
<h1 id="homHeader__title">
|
||||||
isNewKibanaInstance={this.state.isNewKibanaInstance}
|
<FormattedMessage id="home.pageHeader.title" defaultMessage="Home" />
|
||||||
/>
|
</h1>
|
||||||
|
|
||||||
<EuiSpacer size="l" />
|
|
||||||
|
|
||||||
<EuiFlexGroup>
|
|
||||||
<EuiFlexItem>
|
|
||||||
<EuiPanel paddingSize="l">
|
|
||||||
<EuiTitle size="s">
|
|
||||||
<h2>
|
|
||||||
<FormattedMessage
|
|
||||||
id="home.directories.visualize.nameTitle"
|
|
||||||
defaultMessage="Visualize and Explore Data"
|
|
||||||
/>
|
|
||||||
</h2>
|
|
||||||
</EuiTitle>
|
</EuiTitle>
|
||||||
<EuiSpacer size="m" />
|
</EuiFlexItem>
|
||||||
<EuiFlexGrid columns={2} gutterSize="s">
|
|
||||||
{this.renderDirectories(FeatureCatalogueCategory.DATA)}
|
<EuiFlexItem grow={false}>
|
||||||
</EuiFlexGrid>
|
<EuiFlexGroup className="homHeader__actions">
|
||||||
</EuiPanel>
|
<EuiFlexItem className="homHeader__actionItem">
|
||||||
|
<EuiButtonEmpty href="#/tutorial_directory" iconType="indexOpen">
|
||||||
|
{i18n.translate('home.pageHeader.addDataButtonLabel', {
|
||||||
|
defaultMessage: 'Add data',
|
||||||
|
})}
|
||||||
|
</EuiButtonEmpty>
|
||||||
|
</EuiFlexItem>
|
||||||
|
|
||||||
|
{stackManagement ? (
|
||||||
|
<EuiFlexItem className="homHeader__actionItem">
|
||||||
|
<EuiButtonEmpty
|
||||||
|
onClick={createAppNavigationHandler(stackManagement.path)}
|
||||||
|
iconType="gear"
|
||||||
|
>
|
||||||
|
{i18n.translate('home.pageHeader.stackManagementButtonLabel', {
|
||||||
|
defaultMessage: 'Manage',
|
||||||
|
})}
|
||||||
|
</EuiButtonEmpty>
|
||||||
|
</EuiFlexItem>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{devTools ? (
|
||||||
|
<EuiFlexItem className="homHeader__actionItem">
|
||||||
|
<EuiButtonEmpty
|
||||||
|
onClick={createAppNavigationHandler(devTools.path)}
|
||||||
|
iconType="wrench"
|
||||||
|
>
|
||||||
|
{i18n.translate('home.pageHeader.devToolsButtonLabel', {
|
||||||
|
defaultMessage: 'Dev tools',
|
||||||
|
})}
|
||||||
|
</EuiButtonEmpty>
|
||||||
|
</EuiFlexItem>
|
||||||
|
) : null}
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div className="homContent">
|
||||||
|
{solutions.length && <SolutionsSection addBasePath={addBasePath} solutions={solutions} />}
|
||||||
|
|
||||||
|
<EuiFlexGroup
|
||||||
|
className={`homData ${
|
||||||
|
addDataFeatures.length === 1 && manageDataFeatures.length === 1
|
||||||
|
? 'homData--compressed'
|
||||||
|
: 'homData--expanded'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<EuiFlexItem>
|
||||||
|
<AddData addBasePath={addBasePath} features={addDataFeatures} />
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
|
|
||||||
<EuiFlexItem>
|
<EuiFlexItem>
|
||||||
<EuiPanel paddingSize="l">
|
<ManageData addBasePath={addBasePath} features={manageDataFeatures} />
|
||||||
<EuiTitle size="s">
|
|
||||||
<h2>
|
|
||||||
<FormattedMessage
|
|
||||||
id="home.directories.manage.nameTitle"
|
|
||||||
defaultMessage="Manage and Administer the Elastic Stack"
|
|
||||||
/>
|
|
||||||
</h2>
|
|
||||||
</EuiTitle>
|
|
||||||
<EuiSpacer size="m" />
|
|
||||||
<EuiFlexGrid columns={2}>
|
|
||||||
{this.renderDirectories(FeatureCatalogueCategory.ADMIN)}
|
|
||||||
</EuiFlexGrid>
|
|
||||||
</EuiPanel>
|
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
</EuiFlexGroup>
|
</EuiFlexGroup>
|
||||||
|
|
||||||
<EuiSpacer size="l" />
|
<EuiHorizontalRule margin="xl" aria-hidden="true" />
|
||||||
|
|
||||||
<EuiFlexGroup justifyContent="center">
|
<footer className="homFooter">
|
||||||
<EuiFlexItem grow={false} className="eui-textCenter">
|
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween">
|
||||||
<EuiText size="s" color="subdued">
|
<EuiFlexItem grow={false}>
|
||||||
<p>
|
{advancedSettings && (
|
||||||
|
<EuiButtonEmpty
|
||||||
|
iconType="home"
|
||||||
|
onClick={createAppNavigationHandler(
|
||||||
|
'/app/management/kibana/settings#defaultRoute'
|
||||||
|
)}
|
||||||
|
size="xs"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id="home.changeHomeRouteLink"
|
||||||
|
defaultMessage="Display a different page on log in"
|
||||||
|
/>
|
||||||
|
</EuiButtonEmpty>
|
||||||
|
)}
|
||||||
|
</EuiFlexItem>
|
||||||
|
|
||||||
|
<EuiFlexItem grow={false}>
|
||||||
|
<EuiButtonEmpty
|
||||||
|
data-test-subj="allPlugins"
|
||||||
|
href="#/feature_directory"
|
||||||
|
size="xs"
|
||||||
|
flush="right"
|
||||||
|
iconType="apps"
|
||||||
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id="home.directories.notFound.description"
|
id="home.appDirectory.appDirectoryButtonLabel"
|
||||||
defaultMessage="Didn’t find what you were looking for?"
|
defaultMessage="View app directory"
|
||||||
/>
|
/>
|
||||||
</p>
|
</EuiButtonEmpty>
|
||||||
</EuiText>
|
</EuiFlexItem>
|
||||||
<EuiSpacer size="s" />
|
</EuiFlexGroup>
|
||||||
<EuiButton data-test-subj="allPlugins" href="#/feature_directory">
|
</footer>
|
||||||
<FormattedMessage
|
</div>
|
||||||
id="home.directories.notFound.viewFullButtonLabel"
|
</main>
|
||||||
defaultMessage="View full directory of Kibana plugins"
|
|
||||||
/>
|
|
||||||
</EuiButton>
|
|
||||||
</EuiFlexItem>
|
|
||||||
</EuiFlexGroup>
|
|
||||||
</EuiPageBody>
|
|
||||||
</EuiPage>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,13 +296,23 @@ Home.propTypes = {
|
||||||
path: PropTypes.string.isRequired,
|
path: PropTypes.string.isRequired,
|
||||||
showOnHomePage: PropTypes.bool.isRequired,
|
showOnHomePage: PropTypes.bool.isRequired,
|
||||||
category: PropTypes.string.isRequired,
|
category: PropTypes.string.isRequired,
|
||||||
|
order: PropTypes.number,
|
||||||
|
})
|
||||||
|
),
|
||||||
|
solutions: PropTypes.arrayOf(
|
||||||
|
PropTypes.shape({
|
||||||
|
id: PropTypes.string.isRequired,
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
|
subtitle: PropTypes.string.isRequired,
|
||||||
|
descriptions: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||||
|
icon: PropTypes.string.isRequired,
|
||||||
|
path: PropTypes.string.isRequired,
|
||||||
|
order: PropTypes.number,
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
apmUiEnabled: PropTypes.bool.isRequired,
|
|
||||||
find: PropTypes.func.isRequired,
|
find: PropTypes.func.isRequired,
|
||||||
localStorage: PropTypes.object.isRequired,
|
localStorage: PropTypes.object.isRequired,
|
||||||
urlBasePath: PropTypes.string.isRequired,
|
urlBasePath: PropTypes.string.isRequired,
|
||||||
mlEnabled: PropTypes.bool.isRequired,
|
|
||||||
telemetry: PropTypes.shape({
|
telemetry: PropTypes.shape({
|
||||||
telemetryService: PropTypes.any,
|
telemetryService: PropTypes.any,
|
||||||
telemetryNotifications: PropTypes.any,
|
telemetryNotifications: PropTypes.any,
|
||||||
|
|
|
@ -41,6 +41,7 @@ describe('home', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
defaultProps = {
|
defaultProps = {
|
||||||
directories: [],
|
directories: [],
|
||||||
|
solutions: [],
|
||||||
apmUiEnabled: true,
|
apmUiEnabled: true,
|
||||||
mlEnabled: true,
|
mlEnabled: true,
|
||||||
kibanaVersion: '99.2.1',
|
kibanaVersion: '99.2.1',
|
||||||
|
@ -92,8 +93,96 @@ describe('home', () => {
|
||||||
expect(component).toMatchSnapshot();
|
expect(component).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('header', () => {
|
||||||
|
test('render', async () => {
|
||||||
|
const component = await renderHome();
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should show "Manage" link if stack management is available', async () => {
|
||||||
|
const directoryEntry = {
|
||||||
|
id: 'stack-management',
|
||||||
|
title: 'Management',
|
||||||
|
description: 'Your center console for managing the Elastic Stack.',
|
||||||
|
icon: 'managementApp',
|
||||||
|
path: 'management_landing_page',
|
||||||
|
category: FeatureCatalogueCategory.ADMIN,
|
||||||
|
showOnHomePage: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const component = await renderHome({
|
||||||
|
directories: [directoryEntry],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should show "Dev tools" link if console is available', async () => {
|
||||||
|
const directoryEntry = {
|
||||||
|
id: 'console',
|
||||||
|
title: 'Console',
|
||||||
|
description: 'Skip cURL and use a JSON interface to work with your data in Console.',
|
||||||
|
icon: 'consoleApp',
|
||||||
|
path: 'path-to-dev-tools',
|
||||||
|
category: FeatureCatalogueCategory.ADMIN,
|
||||||
|
showOnHomePage: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const component = await renderHome({
|
||||||
|
directories: [directoryEntry],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('directories', () => {
|
describe('directories', () => {
|
||||||
test('should render DATA directory entry in "Explore Data" panel', async () => {
|
test('should render solutions in the "solution section"', async () => {
|
||||||
|
const solutionEntry1 = {
|
||||||
|
id: 'kibana',
|
||||||
|
title: 'Kibana',
|
||||||
|
subtitle: 'Visualize & analyze',
|
||||||
|
descriptions: ['Analyze data in dashboards'],
|
||||||
|
icon: 'logoKibana',
|
||||||
|
path: 'kibana_landing_page',
|
||||||
|
order: 1,
|
||||||
|
};
|
||||||
|
const solutionEntry2 = {
|
||||||
|
id: 'solution-2',
|
||||||
|
title: 'Solution two',
|
||||||
|
subtitle: 'Subtitle for solution two',
|
||||||
|
descriptions: ['Example use case'],
|
||||||
|
icon: 'empty',
|
||||||
|
path: 'path-to-solution-two',
|
||||||
|
order: 2,
|
||||||
|
};
|
||||||
|
const solutionEntry3 = {
|
||||||
|
id: 'solution-3',
|
||||||
|
title: 'Solution three',
|
||||||
|
subtitle: 'Subtitle for solution three',
|
||||||
|
descriptions: ['Example use case'],
|
||||||
|
icon: 'empty',
|
||||||
|
path: 'path-to-solution-three',
|
||||||
|
order: 3,
|
||||||
|
};
|
||||||
|
const solutionEntry4 = {
|
||||||
|
id: 'solution-4',
|
||||||
|
title: 'Solution four',
|
||||||
|
subtitle: 'Subtitle for solution four',
|
||||||
|
descriptions: ['Example use case'],
|
||||||
|
icon: 'empty',
|
||||||
|
path: 'path-to-solution-four',
|
||||||
|
order: 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
const component = await renderHome({
|
||||||
|
solutions: [solutionEntry1, solutionEntry2, solutionEntry3, solutionEntry4],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render DATA directory entry in "Ingest your data" panel', async () => {
|
||||||
const directoryEntry = {
|
const directoryEntry = {
|
||||||
id: 'dashboard',
|
id: 'dashboard',
|
||||||
title: 'Dashboard',
|
title: 'Dashboard',
|
||||||
|
@ -111,7 +200,7 @@ describe('home', () => {
|
||||||
expect(component).toMatchSnapshot();
|
expect(component).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should render ADMIN directory entry in "Manage" panel', async () => {
|
test('should render ADMIN directory entry in "Manage your data" panel', async () => {
|
||||||
const directoryEntry = {
|
const directoryEntry = {
|
||||||
id: 'index_patterns',
|
id: 'index_patterns',
|
||||||
title: 'Index Patterns',
|
title: 'Index Patterns',
|
||||||
|
@ -148,6 +237,26 @@ describe('home', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('change home route', () => {
|
||||||
|
test('should render a link to change the default route in advanced settings if advanced settings is enabled', async () => {
|
||||||
|
const component = await renderHome({
|
||||||
|
directories: [
|
||||||
|
{
|
||||||
|
description: 'Change your settings',
|
||||||
|
icon: 'gear',
|
||||||
|
id: 'advanced_settings',
|
||||||
|
path: 'path-to-advanced_settings',
|
||||||
|
showOnHomePage: false,
|
||||||
|
title: 'Advanced settings',
|
||||||
|
category: FeatureCatalogueCategory.ADMIN,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('welcome', () => {
|
describe('welcome', () => {
|
||||||
test('should show the welcome screen if enabled, and there are no index patterns defined', async () => {
|
test('should show the welcome screen if enabled, and there are no index patterns defined', async () => {
|
||||||
defaultProps.localStorage.getItem = sinon.spy(() => 'true');
|
defaultProps.localStorage.getItem = sinon.spy(() => 'true');
|
||||||
|
|
|
@ -38,7 +38,7 @@ const RedirectToDefaultApp = () => {
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function HomeApp({ directories }) {
|
export function HomeApp({ directories, solutions }) {
|
||||||
const {
|
const {
|
||||||
savedObjectsClient,
|
savedObjectsClient,
|
||||||
getBasePath,
|
getBasePath,
|
||||||
|
@ -48,8 +48,6 @@ export function HomeApp({ directories }) {
|
||||||
} = getServices();
|
} = getServices();
|
||||||
const environment = environmentService.getEnvironment();
|
const environment = environmentService.getEnvironment();
|
||||||
const isCloudEnabled = environment.cloud;
|
const isCloudEnabled = environment.cloud;
|
||||||
const mlEnabled = environment.ml;
|
|
||||||
const apmUiEnabled = environment.apmUi;
|
|
||||||
|
|
||||||
const renderTutorialDirectory = (props) => {
|
const renderTutorialDirectory = (props) => {
|
||||||
return (
|
return (
|
||||||
|
@ -87,8 +85,7 @@ export function HomeApp({ directories }) {
|
||||||
<Home
|
<Home
|
||||||
addBasePath={addBasePath}
|
addBasePath={addBasePath}
|
||||||
directories={directories}
|
directories={directories}
|
||||||
apmUiEnabled={apmUiEnabled}
|
solutions={solutions}
|
||||||
mlEnabled={mlEnabled}
|
|
||||||
find={savedObjectsClient.find}
|
find={savedObjectsClient.find}
|
||||||
localStorage={localStorage}
|
localStorage={localStorage}
|
||||||
urlBasePath={getBasePath()}
|
urlBasePath={getBasePath()}
|
||||||
|
@ -112,6 +109,18 @@ HomeApp.propTypes = {
|
||||||
path: PropTypes.string.isRequired,
|
path: PropTypes.string.isRequired,
|
||||||
showOnHomePage: PropTypes.bool.isRequired,
|
showOnHomePage: PropTypes.bool.isRequired,
|
||||||
category: PropTypes.string.isRequired,
|
category: PropTypes.string.isRequired,
|
||||||
|
order: PropTypes.number,
|
||||||
|
})
|
||||||
|
),
|
||||||
|
solutions: PropTypes.arrayOf(
|
||||||
|
PropTypes.shape({
|
||||||
|
id: PropTypes.string.isRequired,
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
|
subtitle: PropTypes.string.isRequired,
|
||||||
|
descriptions: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||||
|
icon: PropTypes.string.isRequired,
|
||||||
|
path: PropTypes.string.isRequired,
|
||||||
|
order: PropTypes.number,
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
91
src/plugins/home/public/application/components/manage_data/__snapshots__/manage_data.test.tsx.snap
generated
Normal file
91
src/plugins/home/public/application/components/manage_data/__snapshots__/manage_data.test.tsx.snap
generated
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`ManageData render 1`] = `
|
||||||
|
<Fragment>
|
||||||
|
<EuiHorizontalRule
|
||||||
|
aria-hidden="true"
|
||||||
|
margin="xl"
|
||||||
|
/>
|
||||||
|
<section
|
||||||
|
aria-labelledby="homDataManage__title"
|
||||||
|
className="homDataManage"
|
||||||
|
>
|
||||||
|
<EuiTitle
|
||||||
|
size="s"
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
id="homDataManage__title"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Manage your data"
|
||||||
|
id="home.manageData.sectionTitle"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</h2>
|
||||||
|
</EuiTitle>
|
||||||
|
<EuiSpacer
|
||||||
|
size="m"
|
||||||
|
/>
|
||||||
|
<EuiFlexGroup
|
||||||
|
className="homDataManage__content"
|
||||||
|
>
|
||||||
|
<EuiFlexItem
|
||||||
|
key="security"
|
||||||
|
>
|
||||||
|
<Synopsis
|
||||||
|
description="Control who has access and what tasks they can perform."
|
||||||
|
iconType="securityApp"
|
||||||
|
id="security"
|
||||||
|
isBeta={false}
|
||||||
|
onClick={[Function]}
|
||||||
|
title="Protect your data"
|
||||||
|
url="path-to-security-roles"
|
||||||
|
wrapInPanel={true}
|
||||||
|
/>
|
||||||
|
</EuiFlexItem>
|
||||||
|
<EuiFlexItem
|
||||||
|
key="monitoring"
|
||||||
|
>
|
||||||
|
<Synopsis
|
||||||
|
description="Track the real-time health and performance of your deployment."
|
||||||
|
iconType="monitoringApp"
|
||||||
|
id="monitoring"
|
||||||
|
isBeta={false}
|
||||||
|
onClick={[Function]}
|
||||||
|
title="Monitor the stack"
|
||||||
|
url="path-to-monitoring"
|
||||||
|
wrapInPanel={true}
|
||||||
|
/>
|
||||||
|
</EuiFlexItem>
|
||||||
|
<EuiFlexItem
|
||||||
|
key="snapshot_restore"
|
||||||
|
>
|
||||||
|
<Synopsis
|
||||||
|
description="Save snapshots to a backup repository, and restore to recover index and cluster state."
|
||||||
|
iconType="storage"
|
||||||
|
id="snapshot_restore"
|
||||||
|
isBeta={false}
|
||||||
|
onClick={[Function]}
|
||||||
|
title="Store & recover backups"
|
||||||
|
url="path-to-snapshot-restore"
|
||||||
|
wrapInPanel={true}
|
||||||
|
/>
|
||||||
|
</EuiFlexItem>
|
||||||
|
<EuiFlexItem
|
||||||
|
key="index_lifecycle_management"
|
||||||
|
>
|
||||||
|
<Synopsis
|
||||||
|
description="Define lifecycle policies to automatically perform operations as an index ages."
|
||||||
|
iconType="indexSettings"
|
||||||
|
id="index_lifecycle_management"
|
||||||
|
isBeta={false}
|
||||||
|
onClick={[Function]}
|
||||||
|
title="Manage index lifecycles"
|
||||||
|
url="path-to-index-lifecycle-management"
|
||||||
|
wrapInPanel={true}
|
||||||
|
/>
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</section>
|
||||||
|
</Fragment>
|
||||||
|
`;
|
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './manage_data';
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { ManageData } from './manage_data';
|
||||||
|
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||||
|
|
||||||
|
jest.mock('../app_navigation_handler', () => {
|
||||||
|
return {
|
||||||
|
createAppNavigationHandler: jest.fn(() => () => {}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
const addBasePathMock = jest.fn((path: string) => (path ? path : 'path'));
|
||||||
|
|
||||||
|
const mockFeatures = [
|
||||||
|
{
|
||||||
|
category: 'admin',
|
||||||
|
description: 'Control who has access and what tasks they can perform.',
|
||||||
|
homePageSection: 'manage_data',
|
||||||
|
icon: 'securityApp',
|
||||||
|
id: 'security',
|
||||||
|
order: 600,
|
||||||
|
path: 'path-to-security-roles',
|
||||||
|
title: 'Protect your data',
|
||||||
|
showOnHomePage: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: 'admin',
|
||||||
|
description: 'Track the real-time health and performance of your deployment.',
|
||||||
|
homePageSection: 'manage_data',
|
||||||
|
icon: 'monitoringApp',
|
||||||
|
id: 'monitoring',
|
||||||
|
order: 610,
|
||||||
|
path: 'path-to-monitoring',
|
||||||
|
title: 'Monitor the stack',
|
||||||
|
showOnHomePage: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: 'admin',
|
||||||
|
description:
|
||||||
|
'Save snapshots to a backup repository, and restore to recover index and cluster state.',
|
||||||
|
homePageSection: 'manage_data',
|
||||||
|
icon: 'storage',
|
||||||
|
id: 'snapshot_restore',
|
||||||
|
order: 630,
|
||||||
|
path: 'path-to-snapshot-restore',
|
||||||
|
title: 'Store & recover backups',
|
||||||
|
showOnHomePage: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: 'admin',
|
||||||
|
description: 'Define lifecycle policies to automatically perform operations as an index ages.',
|
||||||
|
homePageSection: 'manage_data',
|
||||||
|
icon: 'indexSettings',
|
||||||
|
id: 'index_lifecycle_management',
|
||||||
|
order: 640,
|
||||||
|
path: 'path-to-index-lifecycle-management',
|
||||||
|
title: 'Manage index lifecycles',
|
||||||
|
showOnHomePage: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
describe('ManageData', () => {
|
||||||
|
test('render', () => {
|
||||||
|
const component = shallowWithIntl(
|
||||||
|
<ManageData addBasePath={addBasePathMock} features={mockFeatures} />
|
||||||
|
);
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { FC } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { EuiFlexGroup, EuiHorizontalRule, EuiSpacer, EuiTitle, EuiFlexItem } from '@elastic/eui';
|
||||||
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
// @ts-expect-error untyped service
|
||||||
|
import { FeatureCatalogueEntry } from '../../services';
|
||||||
|
import { createAppNavigationHandler } from '../app_navigation_handler';
|
||||||
|
// @ts-expect-error untyped component
|
||||||
|
import { Synopsis } from '../synopsis';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
addBasePath: (path: string) => string;
|
||||||
|
features: FeatureCatalogueEntry[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ManageData: FC<Props> = ({ addBasePath, features }) => (
|
||||||
|
<>
|
||||||
|
{features.length > 1 && <EuiHorizontalRule margin="xl" aria-hidden="true" />}
|
||||||
|
|
||||||
|
<section className="homDataManage" aria-labelledby="homDataManage__title">
|
||||||
|
<EuiTitle size="s">
|
||||||
|
<h2 id="homDataManage__title">
|
||||||
|
<FormattedMessage id="home.manageData.sectionTitle" defaultMessage="Manage your data" />
|
||||||
|
</h2>
|
||||||
|
</EuiTitle>
|
||||||
|
|
||||||
|
<EuiSpacer size="m" />
|
||||||
|
|
||||||
|
<EuiFlexGroup className="homDataManage__content">
|
||||||
|
{features.map((feature) => (
|
||||||
|
<EuiFlexItem key={feature.id}>
|
||||||
|
<Synopsis
|
||||||
|
id={feature.id}
|
||||||
|
onClick={createAppNavigationHandler(feature.path)}
|
||||||
|
description={feature.description}
|
||||||
|
iconType={feature.icon}
|
||||||
|
title={feature.title}
|
||||||
|
url={addBasePath(feature.path)}
|
||||||
|
wrapInPanel
|
||||||
|
/>
|
||||||
|
</EuiFlexItem>
|
||||||
|
))}
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</section>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
ManageData.propTypes = {
|
||||||
|
addBasePath: PropTypes.func.isRequired,
|
||||||
|
features: PropTypes.arrayOf(
|
||||||
|
PropTypes.shape({
|
||||||
|
id: PropTypes.string.isRequired,
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
|
description: PropTypes.string.isRequired,
|
||||||
|
icon: PropTypes.string.isRequired,
|
||||||
|
path: PropTypes.string.isRequired,
|
||||||
|
showOnHomePage: PropTypes.bool.isRequired,
|
||||||
|
category: PropTypes.string.isRequired,
|
||||||
|
order: PropTypes.number,
|
||||||
|
})
|
||||||
|
),
|
||||||
|
};
|
|
@ -0,0 +1,47 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`SolutionPanel renders the solution panel for the given solution 1`] = `
|
||||||
|
<EuiFlexItem
|
||||||
|
className="homSolutions__group homSolutions__group--single homSolutions__item"
|
||||||
|
grow={1}
|
||||||
|
key="kibana"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
className="homSolutionPanel homSolutionPanel--kibana"
|
||||||
|
href="kibana_landing_page"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<EuiPanel
|
||||||
|
paddingSize="none"
|
||||||
|
>
|
||||||
|
<EuiFlexGroup
|
||||||
|
gutterSize="none"
|
||||||
|
>
|
||||||
|
<EuiFlexItem
|
||||||
|
className="homSolutionPanel__header"
|
||||||
|
grow={1}
|
||||||
|
>
|
||||||
|
<SolutionTitle
|
||||||
|
iconType="logoKibana"
|
||||||
|
subtitle="Visualize & analyze"
|
||||||
|
title="Kibana"
|
||||||
|
/>
|
||||||
|
</EuiFlexItem>
|
||||||
|
<EuiFlexItem
|
||||||
|
className="homSolutionPanel__content"
|
||||||
|
grow={1}
|
||||||
|
>
|
||||||
|
<EuiText
|
||||||
|
key="Analyze data in dashboards"
|
||||||
|
size="s"
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
Analyze data in dashboards
|
||||||
|
</p>
|
||||||
|
</EuiText>
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</EuiPanel>
|
||||||
|
</a>
|
||||||
|
</EuiFlexItem>
|
||||||
|
`;
|
|
@ -0,0 +1,41 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`SolutionTitle renders the title section of the solution panel 1`] = `
|
||||||
|
<EuiFlexGroup
|
||||||
|
alignItems="center"
|
||||||
|
gutterSize="none"
|
||||||
|
>
|
||||||
|
<EuiFlexItem
|
||||||
|
className="eui-textCenter"
|
||||||
|
>
|
||||||
|
<EuiToken
|
||||||
|
className="homSolutionPanel__icon"
|
||||||
|
fill="light"
|
||||||
|
iconType="logoKibana"
|
||||||
|
shape="circle"
|
||||||
|
size="l"
|
||||||
|
/>
|
||||||
|
<EuiTitle
|
||||||
|
className="eui-textInheritColor"
|
||||||
|
size="s"
|
||||||
|
>
|
||||||
|
<h3>
|
||||||
|
Kibana
|
||||||
|
</h3>
|
||||||
|
</EuiTitle>
|
||||||
|
<EuiText
|
||||||
|
size="s"
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
className="homSolutionPanel__subtitle"
|
||||||
|
>
|
||||||
|
Visualize & analyze
|
||||||
|
|
||||||
|
<EuiIcon
|
||||||
|
type="sortRight"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</EuiText>
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
`;
|
|
@ -0,0 +1,288 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`SolutionsSection only renders a spacer if no solutions are available 1`] = `
|
||||||
|
<Fragment>
|
||||||
|
<section
|
||||||
|
aria-labelledby="homSolutions__title"
|
||||||
|
className="homSolutions"
|
||||||
|
>
|
||||||
|
<EuiScreenReaderOnly>
|
||||||
|
<EuiTitle
|
||||||
|
size="s"
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
id="homSolutions__title"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Pick your solution"
|
||||||
|
id="home.solutionsSection.sectionTitle"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</h2>
|
||||||
|
</EuiTitle>
|
||||||
|
</EuiScreenReaderOnly>
|
||||||
|
<EuiFlexGroup
|
||||||
|
className="homSolutions__content"
|
||||||
|
justifyContent="spaceAround"
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
<EuiHorizontalRule
|
||||||
|
aria-hidden="true"
|
||||||
|
margin="xl"
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`SolutionsSection renders a single solution 1`] = `
|
||||||
|
<Fragment>
|
||||||
|
<section
|
||||||
|
aria-labelledby="homSolutions__title"
|
||||||
|
className="homSolutions"
|
||||||
|
>
|
||||||
|
<EuiScreenReaderOnly>
|
||||||
|
<EuiTitle
|
||||||
|
size="s"
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
id="homSolutions__title"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Pick your solution"
|
||||||
|
id="home.solutionsSection.sectionTitle"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</h2>
|
||||||
|
</EuiTitle>
|
||||||
|
</EuiScreenReaderOnly>
|
||||||
|
<EuiFlexGroup
|
||||||
|
className="homSolutions__content"
|
||||||
|
justifyContent="spaceAround"
|
||||||
|
>
|
||||||
|
<SolutionPanel
|
||||||
|
addBasePath={[Function]}
|
||||||
|
solution={
|
||||||
|
Object {
|
||||||
|
"descriptions": Array [
|
||||||
|
"Analyze data in dashboards",
|
||||||
|
],
|
||||||
|
"icon": "logoKibana",
|
||||||
|
"id": "kibana",
|
||||||
|
"order": 1,
|
||||||
|
"path": "kibana_landing_page",
|
||||||
|
"subtitle": "Visualize & analyze",
|
||||||
|
"title": "Kibana",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</section>
|
||||||
|
<EuiHorizontalRule
|
||||||
|
aria-hidden="true"
|
||||||
|
margin="xl"
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`SolutionsSection renders multiple solutions in a single column when Kibana apps are not enabled 1`] = `
|
||||||
|
<Fragment>
|
||||||
|
<section
|
||||||
|
aria-labelledby="homSolutions__title"
|
||||||
|
className="homSolutions"
|
||||||
|
>
|
||||||
|
<EuiScreenReaderOnly>
|
||||||
|
<EuiTitle
|
||||||
|
size="s"
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
id="homSolutions__title"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Pick your solution"
|
||||||
|
id="home.solutionsSection.sectionTitle"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</h2>
|
||||||
|
</EuiTitle>
|
||||||
|
</EuiScreenReaderOnly>
|
||||||
|
<EuiFlexGroup
|
||||||
|
className="homSolutions__content"
|
||||||
|
justifyContent="spaceAround"
|
||||||
|
>
|
||||||
|
<EuiFlexItem
|
||||||
|
className="homSolutions__group homSolutions__group--multiple"
|
||||||
|
grow={1}
|
||||||
|
>
|
||||||
|
<EuiFlexGroup
|
||||||
|
direction="column"
|
||||||
|
>
|
||||||
|
<SolutionPanel
|
||||||
|
addBasePath={[Function]}
|
||||||
|
key="solution-2"
|
||||||
|
solution={
|
||||||
|
Object {
|
||||||
|
"descriptions": Array [
|
||||||
|
"Example use case",
|
||||||
|
],
|
||||||
|
"icon": "empty",
|
||||||
|
"id": "solution-2",
|
||||||
|
"order": 2,
|
||||||
|
"path": "path-to-solution-two",
|
||||||
|
"subtitle": "Subtitle for solution two",
|
||||||
|
"title": "Solution two",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<SolutionPanel
|
||||||
|
addBasePath={[Function]}
|
||||||
|
key="solution-3"
|
||||||
|
solution={
|
||||||
|
Object {
|
||||||
|
"descriptions": Array [
|
||||||
|
"Example use case",
|
||||||
|
],
|
||||||
|
"icon": "empty",
|
||||||
|
"id": "solution-3",
|
||||||
|
"order": 3,
|
||||||
|
"path": "path-to-solution-three",
|
||||||
|
"subtitle": "Subtitle for solution three",
|
||||||
|
"title": "Solution three",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<SolutionPanel
|
||||||
|
addBasePath={[Function]}
|
||||||
|
key="solution-4"
|
||||||
|
solution={
|
||||||
|
Object {
|
||||||
|
"descriptions": Array [
|
||||||
|
"Example use case",
|
||||||
|
],
|
||||||
|
"icon": "empty",
|
||||||
|
"id": "solution-4",
|
||||||
|
"order": 4,
|
||||||
|
"path": "path-to-solution-four",
|
||||||
|
"subtitle": "Subtitle for solution four",
|
||||||
|
"title": "Solution four",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</section>
|
||||||
|
<EuiHorizontalRule
|
||||||
|
aria-hidden="true"
|
||||||
|
margin="xl"
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`SolutionsSection renders multiple solutions in two columns with Kibana in its own column 1`] = `
|
||||||
|
<Fragment>
|
||||||
|
<section
|
||||||
|
aria-labelledby="homSolutions__title"
|
||||||
|
className="homSolutions"
|
||||||
|
>
|
||||||
|
<EuiScreenReaderOnly>
|
||||||
|
<EuiTitle
|
||||||
|
size="s"
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
id="homSolutions__title"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Pick your solution"
|
||||||
|
id="home.solutionsSection.sectionTitle"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</h2>
|
||||||
|
</EuiTitle>
|
||||||
|
</EuiScreenReaderOnly>
|
||||||
|
<EuiFlexGroup
|
||||||
|
className="homSolutions__content"
|
||||||
|
justifyContent="spaceAround"
|
||||||
|
>
|
||||||
|
<EuiFlexItem
|
||||||
|
className="homSolutions__group homSolutions__group--multiple"
|
||||||
|
grow={1}
|
||||||
|
>
|
||||||
|
<EuiFlexGroup
|
||||||
|
direction="column"
|
||||||
|
>
|
||||||
|
<SolutionPanel
|
||||||
|
addBasePath={[Function]}
|
||||||
|
key="solution-2"
|
||||||
|
solution={
|
||||||
|
Object {
|
||||||
|
"descriptions": Array [
|
||||||
|
"Example use case",
|
||||||
|
],
|
||||||
|
"icon": "empty",
|
||||||
|
"id": "solution-2",
|
||||||
|
"order": 2,
|
||||||
|
"path": "path-to-solution-two",
|
||||||
|
"subtitle": "Subtitle for solution two",
|
||||||
|
"title": "Solution two",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<SolutionPanel
|
||||||
|
addBasePath={[Function]}
|
||||||
|
key="solution-3"
|
||||||
|
solution={
|
||||||
|
Object {
|
||||||
|
"descriptions": Array [
|
||||||
|
"Example use case",
|
||||||
|
],
|
||||||
|
"icon": "empty",
|
||||||
|
"id": "solution-3",
|
||||||
|
"order": 3,
|
||||||
|
"path": "path-to-solution-three",
|
||||||
|
"subtitle": "Subtitle for solution three",
|
||||||
|
"title": "Solution three",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<SolutionPanel
|
||||||
|
addBasePath={[Function]}
|
||||||
|
key="solution-4"
|
||||||
|
solution={
|
||||||
|
Object {
|
||||||
|
"descriptions": Array [
|
||||||
|
"Example use case",
|
||||||
|
],
|
||||||
|
"icon": "empty",
|
||||||
|
"id": "solution-4",
|
||||||
|
"order": 4,
|
||||||
|
"path": "path-to-solution-four",
|
||||||
|
"subtitle": "Subtitle for solution four",
|
||||||
|
"title": "Solution four",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</EuiFlexItem>
|
||||||
|
<SolutionPanel
|
||||||
|
addBasePath={[Function]}
|
||||||
|
solution={
|
||||||
|
Object {
|
||||||
|
"descriptions": Array [
|
||||||
|
"Analyze data in dashboards",
|
||||||
|
],
|
||||||
|
"icon": "logoKibana",
|
||||||
|
"id": "kibana",
|
||||||
|
"order": 1,
|
||||||
|
"path": "kibana_landing_page",
|
||||||
|
"subtitle": "Visualize & analyze",
|
||||||
|
"title": "Kibana",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</section>
|
||||||
|
<EuiHorizontalRule
|
||||||
|
aria-hidden="true"
|
||||||
|
margin="xl"
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
`;
|
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './solutions_section';
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { shallow } from 'enzyme';
|
||||||
|
import { SolutionPanel } from './solution_panel';
|
||||||
|
|
||||||
|
const solutionEntry = {
|
||||||
|
id: 'kibana',
|
||||||
|
title: 'Kibana',
|
||||||
|
subtitle: 'Visualize & analyze',
|
||||||
|
descriptions: ['Analyze data in dashboards'],
|
||||||
|
icon: 'logoKibana',
|
||||||
|
path: 'kibana_landing_page',
|
||||||
|
order: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const addBasePathMock = (path: string) => (path ? path : 'path');
|
||||||
|
|
||||||
|
describe('SolutionPanel', () => {
|
||||||
|
test('renders the solution panel for the given solution', () => {
|
||||||
|
const component = shallow(
|
||||||
|
<SolutionPanel addBasePath={addBasePathMock} solution={solutionEntry} />
|
||||||
|
);
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { FC } from 'react';
|
||||||
|
import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiSpacer, EuiText } from '@elastic/eui';
|
||||||
|
import { FeatureCatalogueSolution } from '../../../';
|
||||||
|
import { createAppNavigationHandler } from '../app_navigation_handler';
|
||||||
|
import { SolutionTitle } from './solution_title';
|
||||||
|
|
||||||
|
const getDescriptionText = (description: string): JSX.Element => (
|
||||||
|
<EuiText size="s" key={`${description}`}>
|
||||||
|
<p>{description}</p>
|
||||||
|
</EuiText>
|
||||||
|
);
|
||||||
|
|
||||||
|
const addSpacersBetweenElementsReducer = (
|
||||||
|
acc: JSX.Element[],
|
||||||
|
element: JSX.Element,
|
||||||
|
index: number,
|
||||||
|
elements: JSX.Element[]
|
||||||
|
) => {
|
||||||
|
acc.push(element);
|
||||||
|
if (index < elements.length - 1) {
|
||||||
|
acc.push(<EuiSpacer key={`homeSolutionsPanel__UseCaseSpacer${index}`} size="m" />);
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDescriptions = (descriptions: string[]) =>
|
||||||
|
descriptions.map(getDescriptionText).reduce<JSX.Element[]>(addSpacersBetweenElementsReducer, []);
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
addBasePath: (path: string) => string;
|
||||||
|
solution: FeatureCatalogueSolution;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SolutionPanel: FC<Props> = ({ addBasePath, solution }) => (
|
||||||
|
<EuiFlexItem
|
||||||
|
key={solution.id}
|
||||||
|
className={`${
|
||||||
|
solution.id === 'kibana' ? 'homSolutions__group homSolutions__group--single' : ''
|
||||||
|
} homSolutions__item`}
|
||||||
|
grow={1}
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
className={`homSolutionPanel homSolutionPanel--${solution.id}`}
|
||||||
|
href={addBasePath(solution.path)}
|
||||||
|
onClick={createAppNavigationHandler(solution.path)}
|
||||||
|
>
|
||||||
|
<EuiPanel paddingSize="none">
|
||||||
|
<EuiFlexGroup gutterSize="none">
|
||||||
|
<EuiFlexItem grow={1} className={`homSolutionPanel__header`}>
|
||||||
|
<SolutionTitle
|
||||||
|
iconType={solution.icon}
|
||||||
|
title={solution.title}
|
||||||
|
subtitle={solution.subtitle}
|
||||||
|
/>
|
||||||
|
</EuiFlexItem>
|
||||||
|
|
||||||
|
<EuiFlexItem grow={1} className="homSolutionPanel__content">
|
||||||
|
{getDescriptions(solution.descriptions)}
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</EuiPanel>
|
||||||
|
</a>
|
||||||
|
</EuiFlexItem>
|
||||||
|
);
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { shallow } from 'enzyme';
|
||||||
|
import { SolutionTitle } from './solution_title';
|
||||||
|
|
||||||
|
const solutionEntry = {
|
||||||
|
id: 'kibana',
|
||||||
|
title: 'Kibana',
|
||||||
|
subtitle: 'Visualize & analyze',
|
||||||
|
descriptions: ['Analyze data in dashboards'],
|
||||||
|
icon: 'logoKibana',
|
||||||
|
path: 'kibana_landing_page',
|
||||||
|
order: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('SolutionTitle', () => {
|
||||||
|
test('renders the title section of the solution panel', () => {
|
||||||
|
const component = shallow(
|
||||||
|
<SolutionTitle
|
||||||
|
title={solutionEntry.title}
|
||||||
|
subtitle={solutionEntry.subtitle}
|
||||||
|
iconType={solutionEntry.icon}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { FC } from 'react';
|
||||||
|
import {
|
||||||
|
EuiFlexGroup,
|
||||||
|
EuiFlexItem,
|
||||||
|
EuiToken,
|
||||||
|
EuiTitle,
|
||||||
|
EuiText,
|
||||||
|
EuiIcon,
|
||||||
|
IconType,
|
||||||
|
} from '@elastic/eui';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
title: string;
|
||||||
|
subtitle: string;
|
||||||
|
iconType: IconType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SolutionTitle: FC<Props> = ({ title, subtitle, iconType }) => (
|
||||||
|
<EuiFlexGroup gutterSize="none" alignItems="center">
|
||||||
|
<EuiFlexItem className="eui-textCenter">
|
||||||
|
<EuiToken
|
||||||
|
iconType={iconType}
|
||||||
|
shape="circle"
|
||||||
|
fill="light"
|
||||||
|
size="l"
|
||||||
|
className="homSolutionPanel__icon"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EuiTitle className="eui-textInheritColor" size="s">
|
||||||
|
<h3>{title}</h3>
|
||||||
|
</EuiTitle>
|
||||||
|
|
||||||
|
<EuiText size="s">
|
||||||
|
<p className="homSolutionPanel__subtitle">
|
||||||
|
{subtitle} <EuiIcon type="sortRight" />
|
||||||
|
</p>
|
||||||
|
</EuiText>
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
);
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { shallow } from 'enzyme';
|
||||||
|
import { SolutionsSection } from './solutions_section';
|
||||||
|
|
||||||
|
const solutionEntry1 = {
|
||||||
|
id: 'kibana',
|
||||||
|
title: 'Kibana',
|
||||||
|
subtitle: 'Visualize & analyze',
|
||||||
|
descriptions: ['Analyze data in dashboards'],
|
||||||
|
icon: 'logoKibana',
|
||||||
|
path: 'kibana_landing_page',
|
||||||
|
order: 1,
|
||||||
|
};
|
||||||
|
const solutionEntry2 = {
|
||||||
|
id: 'solution-2',
|
||||||
|
title: 'Solution two',
|
||||||
|
subtitle: 'Subtitle for solution two',
|
||||||
|
descriptions: ['Example use case'],
|
||||||
|
icon: 'empty',
|
||||||
|
path: 'path-to-solution-two',
|
||||||
|
order: 2,
|
||||||
|
};
|
||||||
|
const solutionEntry3 = {
|
||||||
|
id: 'solution-3',
|
||||||
|
title: 'Solution three',
|
||||||
|
subtitle: 'Subtitle for solution three',
|
||||||
|
descriptions: ['Example use case'],
|
||||||
|
icon: 'empty',
|
||||||
|
path: 'path-to-solution-three',
|
||||||
|
order: 3,
|
||||||
|
};
|
||||||
|
const solutionEntry4 = {
|
||||||
|
id: 'solution-4',
|
||||||
|
title: 'Solution four',
|
||||||
|
subtitle: 'Subtitle for solution four',
|
||||||
|
descriptions: ['Example use case'],
|
||||||
|
icon: 'empty',
|
||||||
|
path: 'path-to-solution-four',
|
||||||
|
order: 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
const addBasePathMock = (path: string) => (path ? path : 'path');
|
||||||
|
|
||||||
|
describe('SolutionsSection', () => {
|
||||||
|
test('only renders a spacer if no solutions are available', () => {
|
||||||
|
const component = shallow(<SolutionsSection addBasePath={addBasePathMock} solutions={[]} />);
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('renders a single solution', () => {
|
||||||
|
const component = shallow(
|
||||||
|
<SolutionsSection addBasePath={addBasePathMock} solutions={[solutionEntry1]} />
|
||||||
|
);
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('renders multiple solutions in two columns with Kibana in its own column', () => {
|
||||||
|
const component = shallow(
|
||||||
|
<SolutionsSection
|
||||||
|
addBasePath={addBasePathMock}
|
||||||
|
solutions={[solutionEntry1, solutionEntry2, solutionEntry3, solutionEntry4]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
test('renders multiple solutions in a single column when Kibana apps are not enabled', () => {
|
||||||
|
const component = shallow(
|
||||||
|
<SolutionsSection
|
||||||
|
addBasePath={addBasePathMock}
|
||||||
|
solutions={[solutionEntry2, solutionEntry3, solutionEntry4]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { FC } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import {
|
||||||
|
EuiFlexGroup,
|
||||||
|
EuiFlexItem,
|
||||||
|
EuiHorizontalRule,
|
||||||
|
EuiScreenReaderOnly,
|
||||||
|
EuiTitle,
|
||||||
|
} from '@elastic/eui';
|
||||||
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
import { SolutionPanel } from './solution_panel';
|
||||||
|
import { FeatureCatalogueSolution } from '../../../';
|
||||||
|
|
||||||
|
const sortByOrder = (
|
||||||
|
{ order: orderA = 0 }: FeatureCatalogueSolution,
|
||||||
|
{ order: orderB = 0 }: FeatureCatalogueSolution
|
||||||
|
) => orderA - orderB;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
addBasePath: (path: string) => string;
|
||||||
|
solutions: FeatureCatalogueSolution[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SolutionsSection: FC<Props> = ({ addBasePath, solutions }) => {
|
||||||
|
// Separate Kibana from other solutions
|
||||||
|
const kibana = solutions.find(({ id }) => id === 'kibana');
|
||||||
|
solutions = solutions.sort(sortByOrder).filter(({ id }) => id !== 'kibana');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<section aria-labelledby="homSolutions__title" className="homSolutions">
|
||||||
|
<EuiScreenReaderOnly>
|
||||||
|
<EuiTitle size="s">
|
||||||
|
<h2 id="homSolutions__title">
|
||||||
|
<FormattedMessage
|
||||||
|
id="home.solutionsSection.sectionTitle"
|
||||||
|
defaultMessage="Pick your solution"
|
||||||
|
/>
|
||||||
|
</h2>
|
||||||
|
</EuiTitle>
|
||||||
|
</EuiScreenReaderOnly>
|
||||||
|
|
||||||
|
<EuiFlexGroup className="homSolutions__content" justifyContent="spaceAround">
|
||||||
|
{solutions.length ? (
|
||||||
|
<EuiFlexItem grow={1} className="homSolutions__group homSolutions__group--multiple">
|
||||||
|
<EuiFlexGroup direction="column">
|
||||||
|
{solutions.map((solution) => (
|
||||||
|
<SolutionPanel key={solution.id} solution={solution} addBasePath={addBasePath} />
|
||||||
|
))}
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</EuiFlexItem>
|
||||||
|
) : null}
|
||||||
|
{kibana ? <SolutionPanel solution={kibana} addBasePath={addBasePath} /> : null}
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<EuiHorizontalRule margin="xl" aria-hidden="true" />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
SolutionsSection.propTypes = {
|
||||||
|
solutions: PropTypes.arrayOf(
|
||||||
|
PropTypes.shape({
|
||||||
|
id: PropTypes.string.isRequired,
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
|
subtitle: PropTypes.string.isRequired,
|
||||||
|
descriptions: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||||
|
icon: PropTypes.string.isRequired,
|
||||||
|
path: PropTypes.string.isRequired,
|
||||||
|
order: PropTypes.number,
|
||||||
|
})
|
||||||
|
),
|
||||||
|
};
|
|
@ -24,6 +24,7 @@ import classNames from 'classnames';
|
||||||
import { EuiCard, EuiIcon } from '@elastic/eui';
|
import { EuiCard, EuiIcon } from '@elastic/eui';
|
||||||
|
|
||||||
export function Synopsis({
|
export function Synopsis({
|
||||||
|
id,
|
||||||
description,
|
description,
|
||||||
iconUrl,
|
iconUrl,
|
||||||
iconType,
|
iconType,
|
||||||
|
@ -54,8 +55,9 @@ export function Synopsis({
|
||||||
description={description}
|
description={description}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
href={url}
|
href={url}
|
||||||
data-test-subj={`homeSynopsisLink${title.toLowerCase()}`}
|
data-test-subj={`homeSynopsisLink${id.toLowerCase()}`}
|
||||||
betaBadgeLabel={isBeta ? 'Beta' : null}
|
betaBadgeLabel={isBeta ? 'Beta' : null}
|
||||||
|
titleElement="h3"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import { Synopsis } from './synopsis';
|
||||||
test('render', () => {
|
test('render', () => {
|
||||||
const component = shallow(
|
const component = shallow(
|
||||||
<Synopsis
|
<Synopsis
|
||||||
|
id={'tutorial'}
|
||||||
description="this is a great tutorial about..."
|
description="this is a great tutorial about..."
|
||||||
title="Great tutorial"
|
title="Great tutorial"
|
||||||
url="link_to_item"
|
url="link_to_item"
|
||||||
|
@ -37,6 +38,7 @@ describe('props', () => {
|
||||||
test('iconType', () => {
|
test('iconType', () => {
|
||||||
const component = shallow(
|
const component = shallow(
|
||||||
<Synopsis
|
<Synopsis
|
||||||
|
id={'tutorial'}
|
||||||
description="this is a great tutorial about..."
|
description="this is a great tutorial about..."
|
||||||
title="Great tutorial"
|
title="Great tutorial"
|
||||||
url="link_to_item"
|
url="link_to_item"
|
||||||
|
@ -49,6 +51,7 @@ describe('props', () => {
|
||||||
test('iconUrl', () => {
|
test('iconUrl', () => {
|
||||||
const component = shallow(
|
const component = shallow(
|
||||||
<Synopsis
|
<Synopsis
|
||||||
|
id={'tutorial'}
|
||||||
description="this is a great tutorial about..."
|
description="this is a great tutorial about..."
|
||||||
title="Great tutorial"
|
title="Great tutorial"
|
||||||
url="link_to_item"
|
url="link_to_item"
|
||||||
|
@ -61,6 +64,7 @@ describe('props', () => {
|
||||||
test('isBeta', () => {
|
test('isBeta', () => {
|
||||||
const component = shallow(
|
const component = shallow(
|
||||||
<Synopsis
|
<Synopsis
|
||||||
|
id={'tutorial'}
|
||||||
description="this is a great tutorial about..."
|
description="this is a great tutorial about..."
|
||||||
title="Great tutorial"
|
title="Great tutorial"
|
||||||
url="link_to_item"
|
url="link_to_item"
|
||||||
|
|
|
@ -136,6 +136,7 @@ class TutorialDirectoryUi extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
id: tutorialConfig.id,
|
||||||
category: tutorialConfig.category,
|
category: tutorialConfig.category,
|
||||||
icon: icon,
|
icon: icon,
|
||||||
name: tutorialConfig.name,
|
name: tutorialConfig.name,
|
||||||
|
@ -149,6 +150,7 @@ class TutorialDirectoryUi extends React.Component {
|
||||||
|
|
||||||
// Add card for sample data that only gets show in "all" tab
|
// Add card for sample data that only gets show in "all" tab
|
||||||
tutorialCards.push({
|
tutorialCards.push({
|
||||||
|
id: 'sample_data',
|
||||||
name: this.props.intl.formatMessage({
|
name: this.props.intl.formatMessage({
|
||||||
id: 'home.tutorial.card.sampleDataTitle',
|
id: 'home.tutorial.card.sampleDataTitle',
|
||||||
defaultMessage: 'Sample Data',
|
defaultMessage: 'Sample Data',
|
||||||
|
@ -214,6 +216,7 @@ class TutorialDirectoryUi extends React.Component {
|
||||||
return (
|
return (
|
||||||
<EuiFlexItem key={tutorial.name}>
|
<EuiFlexItem key={tutorial.name}>
|
||||||
<Synopsis
|
<Synopsis
|
||||||
|
id={tutorial.id}
|
||||||
iconType={tutorial.icon}
|
iconType={tutorial.icon}
|
||||||
description={tutorial.description}
|
description={tutorial.description}
|
||||||
title={tutorial.name}
|
title={tutorial.name}
|
||||||
|
|
|
@ -27,6 +27,7 @@ export {
|
||||||
} from './plugin';
|
} from './plugin';
|
||||||
export {
|
export {
|
||||||
FeatureCatalogueEntry,
|
FeatureCatalogueEntry,
|
||||||
|
FeatureCatalogueSolution,
|
||||||
FeatureCatalogueCategory,
|
FeatureCatalogueCategory,
|
||||||
Environment,
|
Environment,
|
||||||
TutorialVariables,
|
TutorialVariables,
|
||||||
|
|
|
@ -33,6 +33,42 @@ describe('HomePublicPlugin', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setup', () => {
|
describe('setup', () => {
|
||||||
|
test('registers tutorial directory to feature catalogue', async () => {
|
||||||
|
const setup = await new HomePublicPlugin(mockInitializerContext).setup(
|
||||||
|
coreMock.createSetup() as any,
|
||||||
|
{
|
||||||
|
kibanaLegacy: kibanaLegacyPluginMock.createSetupContract(),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
expect(setup).toHaveProperty('featureCatalogue');
|
||||||
|
expect(setup.featureCatalogue.register).toHaveBeenCalledTimes(1);
|
||||||
|
expect(setup.featureCatalogue.register).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
category: 'data',
|
||||||
|
icon: 'indexOpen',
|
||||||
|
id: 'home_tutorial_directory',
|
||||||
|
showOnHomePage: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('registers kibana solution to feature catalogue', async () => {
|
||||||
|
const setup = await new HomePublicPlugin(mockInitializerContext).setup(
|
||||||
|
coreMock.createSetup() as any,
|
||||||
|
{
|
||||||
|
kibanaLegacy: kibanaLegacyPluginMock.createSetupContract(),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
expect(setup).toHaveProperty('featureCatalogue');
|
||||||
|
expect(setup.featureCatalogue.registerSolution).toHaveBeenCalledTimes(1);
|
||||||
|
expect(setup.featureCatalogue.registerSolution).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
icon: 'logoKibana',
|
||||||
|
id: 'kibana',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test('wires up and returns registry', async () => {
|
test('wires up and returns registry', async () => {
|
||||||
const setup = await new HomePublicPlugin(mockInitializerContext).setup(
|
const setup = await new HomePublicPlugin(mockInitializerContext).setup(
|
||||||
coreMock.createSetup() as any,
|
coreMock.createSetup() as any,
|
||||||
|
|
|
@ -30,6 +30,7 @@ import { first } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
EnvironmentService,
|
EnvironmentService,
|
||||||
EnvironmentServiceSetup,
|
EnvironmentServiceSetup,
|
||||||
|
FeatureCatalogueCategory,
|
||||||
FeatureCatalogueRegistry,
|
FeatureCatalogueRegistry,
|
||||||
FeatureCatalogueRegistrySetup,
|
FeatureCatalogueRegistrySetup,
|
||||||
TutorialService,
|
TutorialService,
|
||||||
|
@ -42,6 +43,7 @@ import { TelemetryPluginStart } from '../../telemetry/public';
|
||||||
import { UsageCollectionSetup } from '../../usage_collection/public';
|
import { UsageCollectionSetup } from '../../usage_collection/public';
|
||||||
import { KibanaLegacySetup, KibanaLegacyStart } from '../../kibana_legacy/public';
|
import { KibanaLegacySetup, KibanaLegacyStart } from '../../kibana_legacy/public';
|
||||||
import { AppNavLinkStatus } from '../../../core/public';
|
import { AppNavLinkStatus } from '../../../core/public';
|
||||||
|
import { PLUGIN_ID, HOME_APP_BASE_PATH } from '../common/constants';
|
||||||
|
|
||||||
export interface HomePluginStartDependencies {
|
export interface HomePluginStartDependencies {
|
||||||
data: DataPublicPluginStart;
|
data: DataPublicPluginStart;
|
||||||
|
@ -68,7 +70,7 @@ export class HomePublicPlugin
|
||||||
{ kibanaLegacy, usageCollection }: HomePluginSetupDependencies
|
{ kibanaLegacy, usageCollection }: HomePluginSetupDependencies
|
||||||
): HomePublicPluginSetup {
|
): HomePublicPluginSetup {
|
||||||
core.application.register({
|
core.application.register({
|
||||||
id: 'home',
|
id: PLUGIN_ID,
|
||||||
title: 'Home',
|
title: 'Home',
|
||||||
navLinkStatus: AppNavLinkStatus.hidden,
|
navLinkStatus: AppNavLinkStatus.hidden,
|
||||||
mount: async (params: AppMountParameters) => {
|
mount: async (params: AppMountParameters) => {
|
||||||
|
@ -109,8 +111,58 @@ export class HomePublicPlugin
|
||||||
});
|
});
|
||||||
kibanaLegacy.forwardApp('home', 'home');
|
kibanaLegacy.forwardApp('home', 'home');
|
||||||
|
|
||||||
|
const featureCatalogue = { ...this.featuresCatalogueRegistry.setup() };
|
||||||
|
|
||||||
|
featureCatalogue.register({
|
||||||
|
id: 'home_tutorial_directory',
|
||||||
|
title: i18n.translate('home.tutorialDirectory.featureCatalogueTitle', {
|
||||||
|
defaultMessage: 'Add data',
|
||||||
|
}),
|
||||||
|
description: i18n.translate('home.tutorialDirectory.featureCatalogueDescription', {
|
||||||
|
defaultMessage: 'Ingest data from popular apps and services.',
|
||||||
|
}),
|
||||||
|
icon: 'indexOpen',
|
||||||
|
showOnHomePage: true,
|
||||||
|
path: `${HOME_APP_BASE_PATH}#/tutorial_directory`,
|
||||||
|
category: 'data' as FeatureCatalogueCategory.DATA,
|
||||||
|
order: 500,
|
||||||
|
});
|
||||||
|
|
||||||
|
featureCatalogue.registerSolution({
|
||||||
|
id: 'kibana',
|
||||||
|
title: i18n.translate('home.kibana.featureCatalogue.title', {
|
||||||
|
defaultMessage: 'Kibana',
|
||||||
|
}),
|
||||||
|
subtitle: i18n.translate('home.kibana.featureCatalogue.subtitle', {
|
||||||
|
defaultMessage: 'Visualize & analyze',
|
||||||
|
}),
|
||||||
|
descriptions: [
|
||||||
|
i18n.translate('home.kibana.featureCatalogueDescription1', {
|
||||||
|
defaultMessage: 'Analyze data in dashboards.',
|
||||||
|
}),
|
||||||
|
i18n.translate('home.kibana.featureCatalogueDescription2', {
|
||||||
|
defaultMessage: 'Search and find insights.',
|
||||||
|
}),
|
||||||
|
i18n.translate('home.kibana.featureCatalogueDescription3', {
|
||||||
|
defaultMessage: 'Design pixel-perfect reports.',
|
||||||
|
}),
|
||||||
|
i18n.translate('home.kibana.featureCatalogueDescription4', {
|
||||||
|
defaultMessage: 'Plot geographic data.',
|
||||||
|
}),
|
||||||
|
i18n.translate('home.kibana.featureCatalogueDescription5', {
|
||||||
|
defaultMessage: 'Model, predict, and detect.',
|
||||||
|
}),
|
||||||
|
i18n.translate('home.kibana.featureCatalogueDescription6', {
|
||||||
|
defaultMessage: 'Reveal patterns and relationships.',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
icon: 'logoKibana',
|
||||||
|
path: '/app/dashboards',
|
||||||
|
order: 400,
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
featureCatalogue: { ...this.featuresCatalogueRegistry.setup() },
|
featureCatalogue,
|
||||||
environment: { ...this.environmentService.setup() },
|
environment: { ...this.environmentService.setup() },
|
||||||
tutorials: { ...this.tutorialService.setup() },
|
tutorials: { ...this.tutorialService.setup() },
|
||||||
};
|
};
|
||||||
|
@ -124,7 +176,7 @@ export class HomePublicPlugin
|
||||||
|
|
||||||
// If the home app is the initial location when loading Kibana...
|
// If the home app is the initial location when loading Kibana...
|
||||||
if (
|
if (
|
||||||
window.location.pathname === http.basePath.prepend(`/app/home`) &&
|
window.location.pathname === http.basePath.prepend(HOME_APP_BASE_PATH) &&
|
||||||
window.location.hash === ''
|
window.location.hash === ''
|
||||||
) {
|
) {
|
||||||
// ...wait for the app to mount initially and then...
|
// ...wait for the app to mount initially and then...
|
||||||
|
@ -157,5 +209,6 @@ export interface HomePublicPluginSetup {
|
||||||
* be replaced by display specific extension points.
|
* be replaced by display specific extension points.
|
||||||
* @deprecated
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
|
|
||||||
environment: EnvironmentSetup;
|
environment: EnvironmentSetup;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import {
|
||||||
const createSetupMock = (): jest.Mocked<FeatureCatalogueRegistrySetup> => {
|
const createSetupMock = (): jest.Mocked<FeatureCatalogueRegistrySetup> => {
|
||||||
const setup = {
|
const setup = {
|
||||||
register: jest.fn(),
|
register: jest.fn(),
|
||||||
|
registerSolution: jest.fn(),
|
||||||
};
|
};
|
||||||
return setup;
|
return setup;
|
||||||
};
|
};
|
||||||
|
@ -34,6 +35,7 @@ const createMock = (): jest.Mocked<PublicMethodsOf<FeatureCatalogueRegistry>> =>
|
||||||
setup: jest.fn(),
|
setup: jest.fn(),
|
||||||
start: jest.fn(),
|
start: jest.fn(),
|
||||||
get: jest.fn(() => []),
|
get: jest.fn(() => []),
|
||||||
|
getSolutions: jest.fn(() => []),
|
||||||
};
|
};
|
||||||
service.setup.mockImplementation(createSetupMock);
|
service.setup.mockImplementation(createSetupMock);
|
||||||
return service;
|
return service;
|
||||||
|
|
|
@ -21,6 +21,7 @@ import {
|
||||||
FeatureCatalogueRegistry,
|
FeatureCatalogueRegistry,
|
||||||
FeatureCatalogueCategory,
|
FeatureCatalogueCategory,
|
||||||
FeatureCatalogueEntry,
|
FeatureCatalogueEntry,
|
||||||
|
FeatureCatalogueSolution,
|
||||||
} from './feature_catalogue_registry';
|
} from './feature_catalogue_registry';
|
||||||
|
|
||||||
const DASHBOARD_FEATURE: FeatureCatalogueEntry = {
|
const DASHBOARD_FEATURE: FeatureCatalogueEntry = {
|
||||||
|
@ -33,15 +34,32 @@ const DASHBOARD_FEATURE: FeatureCatalogueEntry = {
|
||||||
category: FeatureCatalogueCategory.DATA,
|
category: FeatureCatalogueCategory.DATA,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const KIBANA_SOLUTION: FeatureCatalogueSolution = {
|
||||||
|
id: 'kibana',
|
||||||
|
title: 'Kibana',
|
||||||
|
subtitle: 'Visualize & analyze',
|
||||||
|
descriptions: ['Analyze data in dashboards.', 'Search and find insights.'],
|
||||||
|
icon: 'kibanaApp',
|
||||||
|
path: `/app/home`,
|
||||||
|
};
|
||||||
|
|
||||||
describe('FeatureCatalogueRegistry', () => {
|
describe('FeatureCatalogueRegistry', () => {
|
||||||
describe('setup', () => {
|
describe('setup', () => {
|
||||||
test('throws when registering duplicate id', () => {
|
test('throws when registering a feature with a duplicate id', () => {
|
||||||
const setup = new FeatureCatalogueRegistry().setup();
|
const setup = new FeatureCatalogueRegistry().setup();
|
||||||
setup.register(DASHBOARD_FEATURE);
|
setup.register(DASHBOARD_FEATURE);
|
||||||
expect(() => setup.register(DASHBOARD_FEATURE)).toThrowErrorMatchingInlineSnapshot(
|
expect(() => setup.register(DASHBOARD_FEATURE)).toThrowErrorMatchingInlineSnapshot(
|
||||||
`"Feature with id [dashboard] has already been registered. Use a unique id."`
|
`"Feature with id [dashboard] has already been registered. Use a unique id."`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('throws when registering a solution with a duplicate id', () => {
|
||||||
|
const setup = new FeatureCatalogueRegistry().setup();
|
||||||
|
setup.registerSolution(KIBANA_SOLUTION);
|
||||||
|
expect(() => setup.registerSolution(KIBANA_SOLUTION)).toThrowErrorMatchingInlineSnapshot(
|
||||||
|
`"Solution with id [kibana] has already been registered. Use a unique id."`
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('start', () => {
|
describe('start', () => {
|
||||||
|
|
|
@ -43,11 +43,32 @@ export interface FeatureCatalogueEntry {
|
||||||
readonly path: string;
|
readonly path: string;
|
||||||
/** Whether or not this link should be shown on the front page of Kibana. */
|
/** Whether or not this link should be shown on the front page of Kibana. */
|
||||||
readonly showOnHomePage: boolean;
|
readonly showOnHomePage: boolean;
|
||||||
|
/** An ordinal used to sort features relative to one another for display on the home page */
|
||||||
|
readonly order?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @public */
|
||||||
|
export interface FeatureCatalogueSolution {
|
||||||
|
/** Unique string identifier for this solution. */
|
||||||
|
readonly id: string;
|
||||||
|
/** Title of solution displayed to the user. */
|
||||||
|
readonly title: string;
|
||||||
|
/** The tagline of the solution displayed to the user. */
|
||||||
|
readonly subtitle: string;
|
||||||
|
/** A list of use cases for this solution displayed to the user. */
|
||||||
|
readonly descriptions: string[];
|
||||||
|
/** EUI `IconType` for icon to be displayed to the user. EUI supports any known EUI icon, SVG URL, or ReactElement. */
|
||||||
|
readonly icon: IconType;
|
||||||
|
/** URL path to link to this future. Should not include the basePath. */
|
||||||
|
readonly path: string;
|
||||||
|
/** An ordinal used to sort solutions relative to one another for display on the home page */
|
||||||
|
readonly order?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FeatureCatalogueRegistry {
|
export class FeatureCatalogueRegistry {
|
||||||
private capabilities: Capabilities | null = null;
|
private capabilities: Capabilities | null = null;
|
||||||
private readonly features = new Map<string, FeatureCatalogueEntry>();
|
private readonly features = new Map<string, FeatureCatalogueEntry>();
|
||||||
|
private readonly solutions = new Map<string, FeatureCatalogueSolution>();
|
||||||
|
|
||||||
public setup() {
|
public setup() {
|
||||||
return {
|
return {
|
||||||
|
@ -60,6 +81,15 @@ export class FeatureCatalogueRegistry {
|
||||||
|
|
||||||
this.features.set(feature.id, feature);
|
this.features.set(feature.id, feature);
|
||||||
},
|
},
|
||||||
|
registerSolution: (solution: FeatureCatalogueSolution) => {
|
||||||
|
if (this.solutions.has(solution.id)) {
|
||||||
|
throw new Error(
|
||||||
|
`Solution with id [${solution.id}] has already been registered. Use a unique id.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.solutions.set(solution.id, solution);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +106,16 @@ export class FeatureCatalogueRegistry {
|
||||||
.filter((entry) => capabilities.catalogue[entry.id] !== false)
|
.filter((entry) => capabilities.catalogue[entry.id] !== false)
|
||||||
.sort(compareByKey('title'));
|
.sort(compareByKey('title'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getSolutions(): readonly FeatureCatalogueSolution[] {
|
||||||
|
if (this.capabilities === null) {
|
||||||
|
throw new Error('Catalogue entries are only available after start phase');
|
||||||
|
}
|
||||||
|
const capabilities = this.capabilities;
|
||||||
|
return [...this.solutions.values()]
|
||||||
|
.filter((solution) => capabilities.catalogue[solution.id] !== false)
|
||||||
|
.sort(compareByKey('title'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FeatureCatalogueRegistrySetup = ReturnType<FeatureCatalogueRegistry['setup']>;
|
export type FeatureCatalogueRegistrySetup = ReturnType<FeatureCatalogueRegistry['setup']>;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
export {
|
export {
|
||||||
FeatureCatalogueCategory,
|
FeatureCatalogueCategory,
|
||||||
FeatureCatalogueEntry,
|
FeatureCatalogueEntry,
|
||||||
|
FeatureCatalogueSolution,
|
||||||
FeatureCatalogueRegistry,
|
FeatureCatalogueRegistry,
|
||||||
FeatureCatalogueRegistrySetup,
|
FeatureCatalogueRegistrySetup,
|
||||||
} from './feature_catalogue_registry';
|
} from './feature_catalogue_registry';
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
"version": "kibana",
|
"version": "kibana",
|
||||||
"server": true,
|
"server": true,
|
||||||
"ui": true,
|
"ui": true,
|
||||||
"requiredPlugins": ["kibanaLegacy", "home"],
|
"requiredPlugins": ["kibanaLegacy"],
|
||||||
"requiredBundles": ["kibanaReact", "kibanaUtils"]
|
"optionalPlugins": ["home"],
|
||||||
|
"requiredBundles": ["kibanaReact", "kibanaUtils", "home"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ import {
|
||||||
} from './management_sections_service';
|
} from './management_sections_service';
|
||||||
|
|
||||||
interface ManagementSetupDependencies {
|
interface ManagementSetupDependencies {
|
||||||
home: HomePublicPluginSetup;
|
home?: HomePublicPluginSetup;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ManagementPlugin implements Plugin<ManagementSetup, ManagementStart> {
|
export class ManagementPlugin implements Plugin<ManagementSetup, ManagementStart> {
|
||||||
|
@ -46,19 +46,21 @@ export class ManagementPlugin implements Plugin<ManagementSetup, ManagementStart
|
||||||
public setup(core: CoreSetup, { home }: ManagementSetupDependencies) {
|
public setup(core: CoreSetup, { home }: ManagementSetupDependencies) {
|
||||||
const kibanaVersion = this.initializerContext.env.packageInfo.version;
|
const kibanaVersion = this.initializerContext.env.packageInfo.version;
|
||||||
|
|
||||||
home.featureCatalogue.register({
|
if (home) {
|
||||||
id: 'stack-management',
|
home.featureCatalogue.register({
|
||||||
title: i18n.translate('management.stackManagement.managementLabel', {
|
id: 'stack-management',
|
||||||
defaultMessage: 'Stack Management',
|
title: i18n.translate('management.stackManagement.managementLabel', {
|
||||||
}),
|
defaultMessage: 'Stack Management',
|
||||||
description: i18n.translate('management.stackManagement.managementDescription', {
|
}),
|
||||||
defaultMessage: 'Your center console for managing the Elastic Stack.',
|
description: i18n.translate('management.stackManagement.managementDescription', {
|
||||||
}),
|
defaultMessage: 'Your center console for managing the Elastic Stack.',
|
||||||
icon: 'managementApp',
|
}),
|
||||||
path: '/app/management',
|
icon: 'managementApp',
|
||||||
showOnHomePage: false,
|
path: '/app/management',
|
||||||
category: FeatureCatalogueCategory.ADMIN,
|
showOnHomePage: false,
|
||||||
});
|
category: FeatureCatalogueCategory.ADMIN,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
core.application.register({
|
core.application.register({
|
||||||
id: 'management',
|
id: 'management',
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
"version": "kibana",
|
"version": "kibana",
|
||||||
"server": true,
|
"server": true,
|
||||||
"ui": true,
|
"ui": true,
|
||||||
"requiredPlugins": ["home", "management", "data"],
|
"requiredPlugins": ["management", "data"],
|
||||||
"optionalPlugins": ["dashboard", "visualizations", "discover"],
|
"optionalPlugins": ["dashboard", "visualizations", "discover", "home"],
|
||||||
"extraPublicDirs": ["public/lib"],
|
"extraPublicDirs": ["public/lib"],
|
||||||
"requiredBundles": ["kibanaReact"]
|
"requiredBundles": ["kibanaReact", "home"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ export interface SavedObjectsManagementPluginStart {
|
||||||
|
|
||||||
export interface SetupDependencies {
|
export interface SetupDependencies {
|
||||||
management: ManagementSetup;
|
management: ManagementSetup;
|
||||||
home: HomePublicPluginSetup;
|
home?: HomePublicPluginSetup;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StartDependencies {
|
export interface StartDependencies {
|
||||||
|
@ -72,20 +72,22 @@ export class SavedObjectsManagementPlugin
|
||||||
): SavedObjectsManagementPluginSetup {
|
): SavedObjectsManagementPluginSetup {
|
||||||
const actionSetup = this.actionService.setup();
|
const actionSetup = this.actionService.setup();
|
||||||
|
|
||||||
home.featureCatalogue.register({
|
if (home) {
|
||||||
id: 'saved_objects',
|
home.featureCatalogue.register({
|
||||||
title: i18n.translate('savedObjectsManagement.objects.savedObjectsTitle', {
|
id: 'saved_objects',
|
||||||
defaultMessage: 'Saved Objects',
|
title: i18n.translate('savedObjectsManagement.objects.savedObjectsTitle', {
|
||||||
}),
|
defaultMessage: 'Saved Objects',
|
||||||
description: i18n.translate('savedObjectsManagement.objects.savedObjectsDescription', {
|
}),
|
||||||
defaultMessage:
|
description: i18n.translate('savedObjectsManagement.objects.savedObjectsDescription', {
|
||||||
'Import, export, and manage your saved searches, visualizations, and dashboards.',
|
defaultMessage:
|
||||||
}),
|
'Import, export, and manage your saved searches, visualizations, and dashboards.',
|
||||||
icon: 'savedObjectsApp',
|
}),
|
||||||
path: '/app/management/kibana/objects',
|
icon: 'savedObjectsApp',
|
||||||
showOnHomePage: true,
|
path: '/app/management/kibana/objects',
|
||||||
category: FeatureCatalogueCategory.ADMIN,
|
showOnHomePage: false,
|
||||||
});
|
category: FeatureCatalogueCategory.ADMIN,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const kibanaSection = management.sections.section.kibana;
|
const kibanaSection = management.sections.section.kibana;
|
||||||
kibanaSection.registerApp({
|
kibanaSection.registerApp({
|
||||||
|
|
|
@ -221,7 +221,7 @@ export class VisualizePlugin
|
||||||
}),
|
}),
|
||||||
icon: 'visualizeApp',
|
icon: 'visualizeApp',
|
||||||
path: `/app/visualize#${VisualizeConstants.LANDING_PAGE_PATH}`,
|
path: `/app/visualize#${VisualizeConstants.LANDING_PAGE_PATH}`,
|
||||||
showOnHomePage: true,
|
showOnHomePage: false,
|
||||||
category: FeatureCatalogueCategory.DATA,
|
category: FeatureCatalogueCategory.DATA,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,19 +98,19 @@ export function HomePageProvider({ getService, getPageObjects }: FtrProviderCont
|
||||||
}
|
}
|
||||||
|
|
||||||
async clickOnConsole() {
|
async clickOnConsole() {
|
||||||
await testSubjects.click('homeSynopsisLinkconsole');
|
await this.clickSynopsis('console');
|
||||||
}
|
}
|
||||||
async clickOnLogo() {
|
async clickOnLogo() {
|
||||||
await testSubjects.click('logo');
|
await testSubjects.click('logo');
|
||||||
}
|
}
|
||||||
|
|
||||||
async ClickOnLogsData() {
|
async clickOnAddData() {
|
||||||
await testSubjects.click('logsData');
|
await this.clickSynopsis('home_tutorial_directory');
|
||||||
}
|
}
|
||||||
|
|
||||||
// clicks on Active MQ logs
|
// clicks on Active MQ logs
|
||||||
async clickOnLogsTutorial() {
|
async clickOnLogsTutorial() {
|
||||||
await testSubjects.click('homeSynopsisLinkactivemq logs');
|
await this.clickSynopsis('activemqlogs');
|
||||||
}
|
}
|
||||||
|
|
||||||
// clicks on cloud tutorial link
|
// clicks on cloud tutorial link
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
"features",
|
"features",
|
||||||
"apmOss",
|
"apmOss",
|
||||||
"data",
|
"data",
|
||||||
"home",
|
|
||||||
"licensing",
|
"licensing",
|
||||||
"triggers_actions_ui"
|
"triggers_actions_ui"
|
||||||
],
|
],
|
||||||
|
@ -18,7 +17,8 @@
|
||||||
"alerts",
|
"alerts",
|
||||||
"observability",
|
"observability",
|
||||||
"security",
|
"security",
|
||||||
"ml"
|
"ml",
|
||||||
|
"home"
|
||||||
],
|
],
|
||||||
"server": true,
|
"server": true,
|
||||||
"ui": true,
|
"ui": true,
|
||||||
|
@ -32,6 +32,7 @@
|
||||||
"requiredBundles": [
|
"requiredBundles": [
|
||||||
"kibanaReact",
|
"kibanaReact",
|
||||||
"kibanaUtils",
|
"kibanaUtils",
|
||||||
"observability"
|
"observability",
|
||||||
|
"home"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,6 @@ export const featureCatalogueEntry = {
|
||||||
}),
|
}),
|
||||||
icon: 'apmApp',
|
icon: 'apmApp',
|
||||||
path: '/app/apm',
|
path: '/app/apm',
|
||||||
showOnHomePage: true,
|
showOnHomePage: false,
|
||||||
category: FeatureCatalogueCategory.DATA,
|
category: FeatureCatalogueCategory.DATA,
|
||||||
};
|
};
|
||||||
|
|
|
@ -45,7 +45,7 @@ export interface ApmPluginSetupDeps {
|
||||||
alerts?: AlertingPluginPublicSetup;
|
alerts?: AlertingPluginPublicSetup;
|
||||||
data: DataPublicPluginSetup;
|
data: DataPublicPluginSetup;
|
||||||
features: FeaturesPluginSetup;
|
features: FeaturesPluginSetup;
|
||||||
home: HomePublicPluginSetup;
|
home?: HomePublicPluginSetup;
|
||||||
licensing: LicensingPluginSetup;
|
licensing: LicensingPluginSetup;
|
||||||
triggers_actions_ui: TriggersAndActionsUIPublicPluginSetup;
|
triggers_actions_ui: TriggersAndActionsUIPublicPluginSetup;
|
||||||
observability?: ObservabilityPluginSetup;
|
observability?: ObservabilityPluginSetup;
|
||||||
|
@ -69,8 +69,10 @@ export class ApmPlugin implements Plugin<ApmPluginSetup, ApmPluginStart> {
|
||||||
const config = this.initializerContext.config.get();
|
const config = this.initializerContext.config.get();
|
||||||
const pluginSetupDeps = plugins;
|
const pluginSetupDeps = plugins;
|
||||||
|
|
||||||
pluginSetupDeps.home.environment.update({ apmUi: true });
|
if (pluginSetupDeps.home) {
|
||||||
pluginSetupDeps.home.featureCatalogue.register(featureCatalogueEntry);
|
pluginSetupDeps.home.environment.update({ apmUi: true });
|
||||||
|
pluginSetupDeps.home.featureCatalogue.register(featureCatalogueEntry);
|
||||||
|
}
|
||||||
|
|
||||||
if (plugins.observability) {
|
if (plugins.observability) {
|
||||||
const getApmDataHelper = async () => {
|
const getApmDataHelper = async () => {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"configPath": ["xpack", "canvas"],
|
"configPath": ["xpack", "canvas"],
|
||||||
"server": true,
|
"server": true,
|
||||||
"ui": true,
|
"ui": true,
|
||||||
"requiredPlugins": ["bfetch", "data", "embeddable", "expressions", "features", "home", "inspector", "uiActions"],
|
"requiredPlugins": ["bfetch", "data", "embeddable", "expressions", "features", "inspector", "uiActions"],
|
||||||
"optionalPlugins": ["usageCollection"],
|
"optionalPlugins": ["usageCollection", "home"],
|
||||||
"requiredBundles": ["kibanaReact", "maps", "lens", "visualizations", "kibanaUtils", "kibanaLegacy", "discover", "savedObjects", "reporting"]
|
"requiredBundles": ["kibanaReact", "maps", "lens", "visualizations", "kibanaUtils", "kibanaLegacy", "discover", "savedObjects", "reporting", "home"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,6 @@ export const featureCatalogueEntry = {
|
||||||
}),
|
}),
|
||||||
icon: 'canvasApp',
|
icon: 'canvasApp',
|
||||||
path: '/app/canvas',
|
path: '/app/canvas',
|
||||||
showOnHomePage: true,
|
showOnHomePage: false,
|
||||||
category: FeatureCatalogueCategory.DATA,
|
category: FeatureCatalogueCategory.DATA,
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,7 +40,7 @@ export { CoreStart, CoreSetup };
|
||||||
export interface CanvasSetupDeps {
|
export interface CanvasSetupDeps {
|
||||||
data: DataPublicPluginSetup;
|
data: DataPublicPluginSetup;
|
||||||
expressions: ExpressionsSetup;
|
expressions: ExpressionsSetup;
|
||||||
home: HomePublicPluginSetup;
|
home?: HomePublicPluginSetup;
|
||||||
usageCollection?: UsageCollectionSetup;
|
usageCollection?: UsageCollectionSetup;
|
||||||
bfetch: BfetchPublicSetup;
|
bfetch: BfetchPublicSetup;
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,9 @@ export class CanvasPlugin
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
plugins.home.featureCatalogue.register(featureCatalogueEntry);
|
if (plugins.home) {
|
||||||
|
plugins.home.featureCatalogue.register(featureCatalogueEntry);
|
||||||
|
}
|
||||||
|
|
||||||
canvasApi.addArgumentUIs(argTypeSpecs);
|
canvasApi.addArgumentUIs(argTypeSpecs);
|
||||||
canvasApi.addTransitions(transitions);
|
canvasApi.addTransitions(transitions);
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
"id": "enterpriseSearch",
|
"id": "enterpriseSearch",
|
||||||
"version": "kibana",
|
"version": "kibana",
|
||||||
"kibanaVersion": "kibana",
|
"kibanaVersion": "kibana",
|
||||||
"requiredPlugins": ["home", "features", "licensing"],
|
"requiredPlugins": ["features", "licensing"],
|
||||||
"configPath": ["enterpriseSearch"],
|
"configPath": ["enterpriseSearch"],
|
||||||
"optionalPlugins": ["usageCollection", "security"],
|
"optionalPlugins": ["usageCollection", "security", "home"],
|
||||||
"server": true,
|
"server": true,
|
||||||
"ui": true
|
"ui": true,
|
||||||
|
"requiredBundles": ["home"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {
|
||||||
AppMountParameters,
|
AppMountParameters,
|
||||||
HttpSetup,
|
HttpSetup,
|
||||||
} from 'src/core/public';
|
} from 'src/core/public';
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
import {
|
import {
|
||||||
FeatureCatalogueCategory,
|
FeatureCatalogueCategory,
|
||||||
HomePublicPluginSetup,
|
HomePublicPluginSetup,
|
||||||
|
@ -21,7 +21,11 @@ import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/public';
|
||||||
import { LicensingPluginSetup } from '../../licensing/public';
|
import { LicensingPluginSetup } from '../../licensing/public';
|
||||||
|
|
||||||
import { IInitialAppData } from '../common/types';
|
import { IInitialAppData } from '../common/types';
|
||||||
import { APP_SEARCH_PLUGIN, WORKPLACE_SEARCH_PLUGIN } from '../common/constants';
|
import {
|
||||||
|
ENTERPRISE_SEARCH_PLUGIN,
|
||||||
|
APP_SEARCH_PLUGIN,
|
||||||
|
WORKPLACE_SEARCH_PLUGIN,
|
||||||
|
} from '../common/constants';
|
||||||
import { ExternalUrl, IExternalUrl } from './applications/shared/enterprise_search_url';
|
import { ExternalUrl, IExternalUrl } from './applications/shared/enterprise_search_url';
|
||||||
import AppSearchLogo from './applications/app_search/assets/logo.svg';
|
import AppSearchLogo from './applications/app_search/assets/logo.svg';
|
||||||
import WorkplaceSearchLogo from './applications/workplace_search/assets/logo.svg';
|
import WorkplaceSearchLogo from './applications/workplace_search/assets/logo.svg';
|
||||||
|
@ -35,7 +39,7 @@ export interface ClientData extends IInitialAppData {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PluginsSetup {
|
export interface PluginsSetup {
|
||||||
home: HomePublicPluginSetup;
|
home?: HomePublicPluginSetup;
|
||||||
licensing: LicensingPluginSetup;
|
licensing: LicensingPluginSetup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,25 +92,48 @@ export class EnterpriseSearchPlugin implements Plugin {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
plugins.home.featureCatalogue.register({
|
if (plugins.home) {
|
||||||
id: APP_SEARCH_PLUGIN.ID,
|
plugins.home.featureCatalogue.registerSolution({
|
||||||
title: APP_SEARCH_PLUGIN.NAME,
|
id: ENTERPRISE_SEARCH_PLUGIN.ID,
|
||||||
icon: AppSearchLogo,
|
title: ENTERPRISE_SEARCH_PLUGIN.NAME,
|
||||||
description: APP_SEARCH_PLUGIN.DESCRIPTION,
|
subtitle: i18n.translate('xpack.enterpriseSearch.featureCatalogue.subtitle', {
|
||||||
path: APP_SEARCH_PLUGIN.URL,
|
defaultMessage: 'Search everything',
|
||||||
category: FeatureCatalogueCategory.DATA,
|
}),
|
||||||
showOnHomePage: true,
|
icon: 'logoEnterpriseSearch',
|
||||||
});
|
descriptions: [
|
||||||
|
i18n.translate('xpack.enterpriseSearch.featureCatalogueDescription1', {
|
||||||
|
defaultMessage: 'Build a powerful search experience.',
|
||||||
|
}),
|
||||||
|
i18n.translate('xpack.enterpriseSearch.featureCatalogueDescription2', {
|
||||||
|
defaultMessage: 'Connect your users to relevant data.',
|
||||||
|
}),
|
||||||
|
i18n.translate('xpack.enterpriseSearch.featureCatalogueDescription3', {
|
||||||
|
defaultMessage: 'Unify your team content.',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
path: APP_SEARCH_PLUGIN.URL, // TODO: Change this to enterprise search overview page once available
|
||||||
|
});
|
||||||
|
|
||||||
plugins.home.featureCatalogue.register({
|
plugins.home.featureCatalogue.register({
|
||||||
id: WORKPLACE_SEARCH_PLUGIN.ID,
|
id: APP_SEARCH_PLUGIN.ID,
|
||||||
title: WORKPLACE_SEARCH_PLUGIN.NAME,
|
title: APP_SEARCH_PLUGIN.NAME,
|
||||||
icon: WorkplaceSearchLogo,
|
icon: AppSearchLogo,
|
||||||
description: WORKPLACE_SEARCH_PLUGIN.DESCRIPTION,
|
description: APP_SEARCH_PLUGIN.DESCRIPTION,
|
||||||
path: WORKPLACE_SEARCH_PLUGIN.URL,
|
path: APP_SEARCH_PLUGIN.URL,
|
||||||
category: FeatureCatalogueCategory.DATA,
|
category: FeatureCatalogueCategory.DATA,
|
||||||
showOnHomePage: true,
|
showOnHomePage: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
plugins.home.featureCatalogue.register({
|
||||||
|
id: WORKPLACE_SEARCH_PLUGIN.ID,
|
||||||
|
title: WORKPLACE_SEARCH_PLUGIN.NAME,
|
||||||
|
icon: WorkplaceSearchLogo,
|
||||||
|
description: WORKPLACE_SEARCH_PLUGIN.DESCRIPTION,
|
||||||
|
path: WORKPLACE_SEARCH_PLUGIN.URL,
|
||||||
|
category: FeatureCatalogueCategory.DATA,
|
||||||
|
showOnHomePage: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public start(core: CoreStart) {}
|
public start(core: CoreStart) {}
|
||||||
|
|
|
@ -75,7 +75,7 @@ export class EnterpriseSearchPlugin implements Plugin {
|
||||||
icon: 'logoEnterpriseSearch',
|
icon: 'logoEnterpriseSearch',
|
||||||
navLinkId: APP_SEARCH_PLUGIN.ID, // TODO - remove this once functional tests no longer rely on navLinkId
|
navLinkId: APP_SEARCH_PLUGIN.ID, // TODO - remove this once functional tests no longer rely on navLinkId
|
||||||
app: ['kibana', APP_SEARCH_PLUGIN.ID, WORKPLACE_SEARCH_PLUGIN.ID],
|
app: ['kibana', APP_SEARCH_PLUGIN.ID, WORKPLACE_SEARCH_PLUGIN.ID],
|
||||||
catalogue: [APP_SEARCH_PLUGIN.ID, WORKPLACE_SEARCH_PLUGIN.ID],
|
catalogue: [ENTERPRISE_SEARCH_PLUGIN.ID, APP_SEARCH_PLUGIN.ID, WORKPLACE_SEARCH_PLUGIN.ID],
|
||||||
privileges: null,
|
privileges: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -93,6 +93,7 @@ export class EnterpriseSearchPlugin implements Plugin {
|
||||||
workplaceSearch: hasWorkplaceSearchAccess,
|
workplaceSearch: hasWorkplaceSearchAccess,
|
||||||
},
|
},
|
||||||
catalogue: {
|
catalogue: {
|
||||||
|
enterpriseSearch: hasAppSearchAccess || hasWorkplaceSearchAccess,
|
||||||
appSearch: hasAppSearchAccess,
|
appSearch: hasAppSearchAccess,
|
||||||
workplaceSearch: hasWorkplaceSearchAccess,
|
workplaceSearch: hasWorkplaceSearchAccess,
|
||||||
},
|
},
|
||||||
|
|
|
@ -61,7 +61,7 @@ export class GraphPlugin
|
||||||
}),
|
}),
|
||||||
icon: 'graphApp',
|
icon: 'graphApp',
|
||||||
path: '/app/graph',
|
path: '/app/graph',
|
||||||
showOnHomePage: true,
|
showOnHomePage: false,
|
||||||
category: FeatureCatalogueCategory.DATA,
|
category: FeatureCatalogueCategory.DATA,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,8 @@ export class GraphPlugin
|
||||||
throw new Error('Start called before setup');
|
throw new Error('Start called before setup');
|
||||||
}
|
}
|
||||||
this.licensing.license$.subscribe((license) => {
|
this.licensing.license$.subscribe((license) => {
|
||||||
toggleNavLink(checkLicense(license), core.chrome.navLinks);
|
const licenseInformation = checkLicense(license);
|
||||||
|
toggleNavLink(licenseInformation, core.chrome.navLinks);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,18 +4,19 @@
|
||||||
"server": true,
|
"server": true,
|
||||||
"ui": true,
|
"ui": true,
|
||||||
"requiredPlugins": [
|
"requiredPlugins": [
|
||||||
"home",
|
|
||||||
"licensing",
|
"licensing",
|
||||||
"management"
|
"management"
|
||||||
],
|
],
|
||||||
"optionalPlugins": [
|
"optionalPlugins": [
|
||||||
"usageCollection",
|
"usageCollection",
|
||||||
"indexManagement"
|
"indexManagement",
|
||||||
|
"home"
|
||||||
],
|
],
|
||||||
"configPath": ["xpack", "ilm"],
|
"configPath": ["xpack", "ilm"],
|
||||||
"requiredBundles": [
|
"requiredBundles": [
|
||||||
"indexManagement",
|
"indexManagement",
|
||||||
"kibanaReact",
|
"kibanaReact",
|
||||||
"esUiShared"
|
"esUiShared",
|
||||||
|
"home"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,9 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
import { CoreSetup, PluginInitializerContext } from 'src/core/public';
|
import { CoreSetup, PluginInitializerContext } from 'src/core/public';
|
||||||
|
import { FeatureCatalogueCategory } from '../../../../src/plugins/home/public';
|
||||||
import { PLUGIN } from '../common/constants';
|
import { PLUGIN } from '../common/constants';
|
||||||
import { init as initHttp } from './application/services/http';
|
import { init as initHttp } from './application/services/http';
|
||||||
import { init as initDocumentation } from './application/services/documentation';
|
import { init as initDocumentation } from './application/services/documentation';
|
||||||
|
@ -30,7 +31,7 @@ export class IndexLifecycleManagementPlugin {
|
||||||
getStartServices,
|
getStartServices,
|
||||||
} = coreSetup;
|
} = coreSetup;
|
||||||
|
|
||||||
const { usageCollection, management, indexManagement } = plugins;
|
const { usageCollection, management, indexManagement, home } = plugins;
|
||||||
|
|
||||||
// Initialize services even if the app isn't mounted, because they're used by index management extensions.
|
// Initialize services even if the app isn't mounted, because they're used by index management extensions.
|
||||||
initHttp(http);
|
initHttp(http);
|
||||||
|
@ -74,6 +75,24 @@ export class IndexLifecycleManagementPlugin {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (home) {
|
||||||
|
home.featureCatalogue.register({
|
||||||
|
id: PLUGIN.ID,
|
||||||
|
title: i18n.translate('xpack.indexLifecycleMgmt.featureCatalogueTitle', {
|
||||||
|
defaultMessage: 'Manage index lifecycles',
|
||||||
|
}),
|
||||||
|
description: i18n.translate('xpack.indexLifecycleMgmt.featureCatalogueDescription', {
|
||||||
|
defaultMessage:
|
||||||
|
'Define lifecycle policies to automatically perform operations as an index ages.',
|
||||||
|
}),
|
||||||
|
icon: 'indexSettings',
|
||||||
|
path: '/app/management/data/index_lifecycle_management',
|
||||||
|
showOnHomePage: true,
|
||||||
|
category: FeatureCatalogueCategory.ADMIN,
|
||||||
|
order: 640,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (indexManagement) {
|
if (indexManagement) {
|
||||||
addAllExtensions(indexManagement.extensionsService);
|
addAllExtensions(indexManagement.extensionsService);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { HomePublicPluginSetup } from '../../../../src/plugins/home/public';
|
||||||
import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public';
|
import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public';
|
||||||
import { ManagementSetup } from '../../../../src/plugins/management/public';
|
import { ManagementSetup } from '../../../../src/plugins/management/public';
|
||||||
import { IndexManagementPluginSetup } from '../../index_management/public';
|
import { IndexManagementPluginSetup } from '../../index_management/public';
|
||||||
|
@ -12,6 +13,7 @@ export interface PluginsDependencies {
|
||||||
usageCollection?: UsageCollectionSetup;
|
usageCollection?: UsageCollectionSetup;
|
||||||
management: ManagementSetup;
|
management: ManagementSetup;
|
||||||
indexManagement?: IndexManagementPluginSetup;
|
indexManagement?: IndexManagementPluginSetup;
|
||||||
|
home?: HomePublicPluginSetup;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ClientConfigType {
|
export interface ClientConfigType {
|
||||||
|
|
|
@ -6,14 +6,14 @@
|
||||||
"features",
|
"features",
|
||||||
"usageCollection",
|
"usageCollection",
|
||||||
"spaces",
|
"spaces",
|
||||||
"home",
|
|
||||||
"data",
|
"data",
|
||||||
"dataEnhanced",
|
"dataEnhanced",
|
||||||
"visTypeTimeseries",
|
"visTypeTimeseries",
|
||||||
"alerts",
|
"alerts",
|
||||||
"triggers_actions_ui"
|
"triggers_actions_ui"
|
||||||
],
|
],
|
||||||
"optionalPlugins": ["ml", "observability"],
|
"optionalPlugins": ["ml", "observability", "home"],
|
||||||
"server": true,
|
"server": true,
|
||||||
"ui": true,
|
"ui": true,
|
||||||
"configPath": ["xpack", "infra"],
|
"configPath": ["xpack", "infra"],
|
||||||
|
@ -22,6 +22,7 @@
|
||||||
"licenseManagement",
|
"licenseManagement",
|
||||||
"kibanaUtils",
|
"kibanaUtils",
|
||||||
"kibanaReact",
|
"kibanaReact",
|
||||||
"apm"
|
"apm",
|
||||||
|
"home"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,9 @@ export class Plugin implements InfraClientPluginClass {
|
||||||
constructor(_context: PluginInitializerContext) {}
|
constructor(_context: PluginInitializerContext) {}
|
||||||
|
|
||||||
setup(core: InfraClientCoreSetup, pluginsSetup: InfraClientSetupDeps) {
|
setup(core: InfraClientCoreSetup, pluginsSetup: InfraClientSetupDeps) {
|
||||||
registerFeatures(pluginsSetup.home);
|
if (pluginsSetup.home) {
|
||||||
|
registerFeatures(pluginsSetup.home);
|
||||||
|
}
|
||||||
|
|
||||||
pluginsSetup.triggers_actions_ui.alertTypeRegistry.register(createInventoryMetricAlertType());
|
pluginsSetup.triggers_actions_ui.alertTypeRegistry.register(createInventoryMetricAlertType());
|
||||||
pluginsSetup.triggers_actions_ui.alertTypeRegistry.register(getLogsAlertType());
|
pluginsSetup.triggers_actions_ui.alertTypeRegistry.register(getLogsAlertType());
|
||||||
|
|
|
@ -22,7 +22,7 @@ export const registerFeatures = (homePlugin: HomePublicPluginSetup) => {
|
||||||
}),
|
}),
|
||||||
icon: 'metricsApp',
|
icon: 'metricsApp',
|
||||||
path: `/app/metrics`,
|
path: `/app/metrics`,
|
||||||
showOnHomePage: true,
|
showOnHomePage: false,
|
||||||
category: FeatureCatalogueCategory.DATA,
|
category: FeatureCatalogueCategory.DATA,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ export const registerFeatures = (homePlugin: HomePublicPluginSetup) => {
|
||||||
}),
|
}),
|
||||||
icon: 'logsApp',
|
icon: 'logsApp',
|
||||||
path: `/app/logs`,
|
path: `/app/logs`,
|
||||||
showOnHomePage: true,
|
showOnHomePage: false,
|
||||||
category: FeatureCatalogueCategory.DATA,
|
category: FeatureCatalogueCategory.DATA,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,7 +25,7 @@ export type InfraClientStartExports = void;
|
||||||
|
|
||||||
export interface InfraClientSetupDeps {
|
export interface InfraClientSetupDeps {
|
||||||
dataEnhanced: DataEnhancedSetup;
|
dataEnhanced: DataEnhancedSetup;
|
||||||
home: HomePublicPluginSetup;
|
home?: HomePublicPluginSetup;
|
||||||
observability: ObservabilityPluginSetup;
|
observability: ObservabilityPluginSetup;
|
||||||
triggers_actions_ui: TriggersAndActionsUIPublicPluginSetup;
|
triggers_actions_ui: TriggersAndActionsUIPublicPluginSetup;
|
||||||
usageCollection: UsageCollectionSetup;
|
usageCollection: UsageCollectionSetup;
|
||||||
|
|
|
@ -18,7 +18,7 @@ export const METRICS_FEATURE = {
|
||||||
icon: 'metricsApp',
|
icon: 'metricsApp',
|
||||||
navLinkId: 'metrics',
|
navLinkId: 'metrics',
|
||||||
app: ['infra', 'metrics', 'kibana'],
|
app: ['infra', 'metrics', 'kibana'],
|
||||||
catalogue: ['infraops'],
|
catalogue: ['infraops', 'metrics'],
|
||||||
management: {
|
management: {
|
||||||
insightsAndAlerting: ['triggersActions'],
|
insightsAndAlerting: ['triggersActions'],
|
||||||
},
|
},
|
||||||
|
@ -26,7 +26,7 @@ export const METRICS_FEATURE = {
|
||||||
privileges: {
|
privileges: {
|
||||||
all: {
|
all: {
|
||||||
app: ['infra', 'metrics', 'kibana'],
|
app: ['infra', 'metrics', 'kibana'],
|
||||||
catalogue: ['infraops'],
|
catalogue: ['infraops', 'metrics'],
|
||||||
api: ['infra'],
|
api: ['infra'],
|
||||||
savedObject: {
|
savedObject: {
|
||||||
all: ['infrastructure-ui-source'],
|
all: ['infrastructure-ui-source'],
|
||||||
|
@ -42,7 +42,7 @@ export const METRICS_FEATURE = {
|
||||||
},
|
},
|
||||||
read: {
|
read: {
|
||||||
app: ['infra', 'metrics', 'kibana'],
|
app: ['infra', 'metrics', 'kibana'],
|
||||||
catalogue: ['infraops'],
|
catalogue: ['infraops', 'metrics'],
|
||||||
api: ['infra'],
|
api: ['infra'],
|
||||||
savedObject: {
|
savedObject: {
|
||||||
all: [],
|
all: [],
|
||||||
|
@ -68,12 +68,12 @@ export const LOGS_FEATURE = {
|
||||||
icon: 'logsApp',
|
icon: 'logsApp',
|
||||||
navLinkId: 'logs',
|
navLinkId: 'logs',
|
||||||
app: ['infra', 'logs', 'kibana'],
|
app: ['infra', 'logs', 'kibana'],
|
||||||
catalogue: ['infralogging'],
|
catalogue: ['infralogging', 'logs'],
|
||||||
alerting: [LOG_DOCUMENT_COUNT_ALERT_TYPE_ID],
|
alerting: [LOG_DOCUMENT_COUNT_ALERT_TYPE_ID],
|
||||||
privileges: {
|
privileges: {
|
||||||
all: {
|
all: {
|
||||||
app: ['infra', 'logs', 'kibana'],
|
app: ['infra', 'logs', 'kibana'],
|
||||||
catalogue: ['infralogging'],
|
catalogue: ['infralogging', 'logs'],
|
||||||
api: ['infra'],
|
api: ['infra'],
|
||||||
savedObject: {
|
savedObject: {
|
||||||
all: ['infrastructure-ui-source'],
|
all: ['infrastructure-ui-source'],
|
||||||
|
@ -86,7 +86,7 @@ export const LOGS_FEATURE = {
|
||||||
},
|
},
|
||||||
read: {
|
read: {
|
||||||
app: ['infra', 'logs', 'kibana'],
|
app: ['infra', 'logs', 'kibana'],
|
||||||
catalogue: ['infralogging'],
|
catalogue: ['infralogging', 'logs'],
|
||||||
api: ['infra'],
|
api: ['infra'],
|
||||||
alerting: {
|
alerting: {
|
||||||
all: [LOG_DOCUMENT_COUNT_ALERT_TYPE_ID],
|
all: [LOG_DOCUMENT_COUNT_ALERT_TYPE_ID],
|
||||||
|
|
|
@ -7,5 +7,5 @@
|
||||||
"requiredPlugins": ["licensing", "data", "encryptedSavedObjects"],
|
"requiredPlugins": ["licensing", "data", "encryptedSavedObjects"],
|
||||||
"optionalPlugins": ["security", "features", "cloud", "usageCollection", "home"],
|
"optionalPlugins": ["security", "features", "cloud", "usageCollection", "home"],
|
||||||
"extraPublicDirs": ["common"],
|
"extraPublicDirs": ["common"],
|
||||||
"requiredBundles": ["kibanaReact", "esUiShared"]
|
"requiredBundles": ["kibanaReact", "esUiShared", "home"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,13 @@ import {
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/public';
|
import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/public';
|
||||||
import { DataPublicPluginSetup, DataPublicPluginStart } from '../../../../src/plugins/data/public';
|
import { DataPublicPluginSetup, DataPublicPluginStart } from '../../../../src/plugins/data/public';
|
||||||
import { HomePublicPluginSetup } from '../../../../src/plugins/home/public';
|
import {
|
||||||
|
HomePublicPluginSetup,
|
||||||
|
FeatureCatalogueCategory,
|
||||||
|
} from '../../../../src/plugins/home/public';
|
||||||
import { LicensingPluginSetup } from '../../licensing/public';
|
import { LicensingPluginSetup } from '../../licensing/public';
|
||||||
import { PLUGIN_ID, CheckPermissionsResponse, PostIngestSetupResponse } from '../common';
|
import { PLUGIN_ID, CheckPermissionsResponse, PostIngestSetupResponse } from '../common';
|
||||||
|
import { BASE_PATH } from './applications/ingest_manager/constants';
|
||||||
|
|
||||||
import { IngestManagerConfigType } from '../common/types';
|
import { IngestManagerConfigType } from '../common/types';
|
||||||
import { setupRouteService, appRoutesService } from '../common';
|
import { setupRouteService, appRoutesService } from '../common';
|
||||||
|
@ -95,6 +99,21 @@ export class IngestManagerPlugin
|
||||||
deps.home.tutorials.registerDirectoryNotice(PLUGIN_ID, TutorialDirectoryNotice);
|
deps.home.tutorials.registerDirectoryNotice(PLUGIN_ID, TutorialDirectoryNotice);
|
||||||
deps.home.tutorials.registerDirectoryHeaderLink(PLUGIN_ID, TutorialDirectoryHeaderLink);
|
deps.home.tutorials.registerDirectoryHeaderLink(PLUGIN_ID, TutorialDirectoryHeaderLink);
|
||||||
deps.home.tutorials.registerModuleNotice(PLUGIN_ID, TutorialModuleNotice);
|
deps.home.tutorials.registerModuleNotice(PLUGIN_ID, TutorialModuleNotice);
|
||||||
|
|
||||||
|
deps.home.featureCatalogue.register({
|
||||||
|
id: 'ingestManager',
|
||||||
|
title: i18n.translate('xpack.ingestManager.featureCatalogueTitle', {
|
||||||
|
defaultMessage: 'Add Elastic Agent',
|
||||||
|
}),
|
||||||
|
description: i18n.translate('xpack.ingestManager.featureCatalogueDescription', {
|
||||||
|
defaultMessage: 'Add and manage your fleet of Elastic Agents and integrations.',
|
||||||
|
}),
|
||||||
|
icon: 'indexManagementApp',
|
||||||
|
showOnHomePage: true,
|
||||||
|
path: BASE_PATH,
|
||||||
|
category: FeatureCatalogueCategory.DATA,
|
||||||
|
order: 510,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -179,10 +179,12 @@ export class IngestManagerPlugin
|
||||||
icon: 'savedObjectsApp',
|
icon: 'savedObjectsApp',
|
||||||
navLinkId: PLUGIN_ID,
|
navLinkId: PLUGIN_ID,
|
||||||
app: [PLUGIN_ID, 'kibana'],
|
app: [PLUGIN_ID, 'kibana'],
|
||||||
|
catalogue: ['ingestManager'],
|
||||||
privileges: {
|
privileges: {
|
||||||
all: {
|
all: {
|
||||||
api: [`${PLUGIN_ID}-read`, `${PLUGIN_ID}-all`],
|
api: [`${PLUGIN_ID}-read`, `${PLUGIN_ID}-all`],
|
||||||
app: [PLUGIN_ID, 'kibana'],
|
app: [PLUGIN_ID, 'kibana'],
|
||||||
|
catalogue: ['ingestManager'],
|
||||||
savedObject: {
|
savedObject: {
|
||||||
all: allSavedObjectTypes,
|
all: allSavedObjectTypes,
|
||||||
read: [],
|
read: [],
|
||||||
|
@ -192,6 +194,7 @@ export class IngestManagerPlugin
|
||||||
read: {
|
read: {
|
||||||
api: [`${PLUGIN_ID}-read`],
|
api: [`${PLUGIN_ID}-read`],
|
||||||
app: [PLUGIN_ID, 'kibana'],
|
app: [PLUGIN_ID, 'kibana'],
|
||||||
|
catalogue: ['ingestManager'], // TODO: check if this is actually available to read user
|
||||||
savedObject: {
|
savedObject: {
|
||||||
all: [],
|
all: [],
|
||||||
read: allSavedObjectTypes,
|
read: allSavedObjectTypes,
|
||||||
|
|
|
@ -70,7 +70,7 @@ export class LogstashPlugin implements Plugin<void, void, SetupDeps> {
|
||||||
}),
|
}),
|
||||||
icon: 'pipelineApp',
|
icon: 'pipelineApp',
|
||||||
path: '/app/management/ingest/pipelines',
|
path: '/app/management/ingest/pipelines',
|
||||||
showOnHomePage: true,
|
showOnHomePage: false,
|
||||||
category: FeatureCatalogueCategory.ADMIN,
|
category: FeatureCatalogueCategory.ADMIN,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
"licensing",
|
"licensing",
|
||||||
"features",
|
"features",
|
||||||
"inspector",
|
"inspector",
|
||||||
"home",
|
|
||||||
"data",
|
"data",
|
||||||
"fileUpload",
|
"fileUpload",
|
||||||
"uiActions",
|
"uiActions",
|
||||||
|
@ -18,12 +17,14 @@
|
||||||
"usageCollection",
|
"usageCollection",
|
||||||
"share"
|
"share"
|
||||||
],
|
],
|
||||||
|
"optionalPlugins": ["home"],
|
||||||
"ui": true,
|
"ui": true,
|
||||||
"server": true,
|
"server": true,
|
||||||
"extraPublicDirs": ["common/constants"],
|
"extraPublicDirs": ["common/constants"],
|
||||||
"requiredBundles": [
|
"requiredBundles": [
|
||||||
"kibanaReact",
|
"kibanaReact",
|
||||||
"kibanaUtils",
|
"kibanaUtils",
|
||||||
"savedObjects"
|
"savedObjects",
|
||||||
|
"home"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,10 @@ export const featureCatalogueEntry = {
|
||||||
id: APP_ID,
|
id: APP_ID,
|
||||||
title: getAppTitle(),
|
title: getAppTitle(),
|
||||||
description: i18n.translate('xpack.maps.feature.appDescription', {
|
description: i18n.translate('xpack.maps.feature.appDescription', {
|
||||||
defaultMessage: 'Explore geospatial data from Elasticsearch and the Elastic Maps Service',
|
defaultMessage: 'Explore geospatial data from Elasticsearch and the Elastic Maps Service.',
|
||||||
}),
|
}),
|
||||||
icon: APP_ICON,
|
icon: APP_ICON,
|
||||||
path: '/app/maps',
|
path: '/app/maps',
|
||||||
showOnHomePage: true,
|
showOnHomePage: false,
|
||||||
category: FeatureCatalogueCategory.DATA,
|
category: FeatureCatalogueCategory.DATA,
|
||||||
};
|
};
|
||||||
|
|
|
@ -51,7 +51,7 @@ import { StartContract as FileUploadStartContract } from '../../file_upload/publ
|
||||||
|
|
||||||
export interface MapsPluginSetupDependencies {
|
export interface MapsPluginSetupDependencies {
|
||||||
inspector: InspectorSetupContract;
|
inspector: InspectorSetupContract;
|
||||||
home: HomePublicPluginSetup;
|
home?: HomePublicPluginSetup;
|
||||||
visualizations: VisualizationsSetup;
|
visualizations: VisualizationsSetup;
|
||||||
embeddable: EmbeddableSetup;
|
embeddable: EmbeddableSetup;
|
||||||
mapsLegacy: { config: MapsLegacyConfigType };
|
mapsLegacy: { config: MapsLegacyConfigType };
|
||||||
|
@ -108,7 +108,9 @@ export class MapsPlugin
|
||||||
);
|
);
|
||||||
|
|
||||||
plugins.inspector.registerView(MapView);
|
plugins.inspector.registerView(MapView);
|
||||||
plugins.home.featureCatalogue.register(featureCatalogueEntry);
|
if (plugins.home) {
|
||||||
|
plugins.home.featureCatalogue.register(featureCatalogueEntry);
|
||||||
|
}
|
||||||
plugins.visualizations.registerAlias(
|
plugins.visualizations.registerAlias(
|
||||||
getMapsVisTypeAlias(plugins.visualizations, config.showMapVisualizationTypes)
|
getMapsVisTypeAlias(plugins.visualizations, config.showMapVisualizationTypes)
|
||||||
);
|
);
|
||||||
|
|
|
@ -91,6 +91,7 @@ export function getPluginPrivileges() {
|
||||||
admin: {
|
admin: {
|
||||||
...privilege,
|
...privilege,
|
||||||
api: allMlCapabilitiesKeys.map((k) => `ml:${k}`),
|
api: allMlCapabilitiesKeys.map((k) => `ml:${k}`),
|
||||||
|
catalogue: [PLUGIN_ID, `${PLUGIN_ID}_file_data_visualizer`],
|
||||||
ui: allMlCapabilitiesKeys,
|
ui: allMlCapabilitiesKeys,
|
||||||
savedObject: {
|
savedObject: {
|
||||||
all: savedObjects,
|
all: savedObjects,
|
||||||
|
@ -100,6 +101,7 @@ export function getPluginPrivileges() {
|
||||||
user: {
|
user: {
|
||||||
...privilege,
|
...privilege,
|
||||||
api: userMlCapabilitiesKeys.map((k) => `ml:${k}`),
|
api: userMlCapabilitiesKeys.map((k) => `ml:${k}`),
|
||||||
|
catalogue: [PLUGIN_ID],
|
||||||
ui: userMlCapabilitiesKeys,
|
ui: userMlCapabilitiesKeys,
|
||||||
savedObject: {
|
savedObject: {
|
||||||
all: [],
|
all: [],
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
"data",
|
"data",
|
||||||
"cloud",
|
"cloud",
|
||||||
"features",
|
"features",
|
||||||
"home",
|
|
||||||
"licensing",
|
"licensing",
|
||||||
"usageCollection",
|
"usageCollection",
|
||||||
"share",
|
"share",
|
||||||
|
@ -20,6 +19,7 @@
|
||||||
"indexPatternManagement"
|
"indexPatternManagement"
|
||||||
],
|
],
|
||||||
"optionalPlugins": [
|
"optionalPlugins": [
|
||||||
|
"home",
|
||||||
"security",
|
"security",
|
||||||
"spaces",
|
"spaces",
|
||||||
"management",
|
"management",
|
||||||
|
@ -32,6 +32,7 @@
|
||||||
"kibanaUtils",
|
"kibanaUtils",
|
||||||
"kibanaReact",
|
"kibanaReact",
|
||||||
"dashboard",
|
"dashboard",
|
||||||
"savedObjects"
|
"savedObjects",
|
||||||
|
"home"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ export interface MlSetupDependencies {
|
||||||
management?: ManagementSetup;
|
management?: ManagementSetup;
|
||||||
usageCollection: UsageCollectionSetup;
|
usageCollection: UsageCollectionSetup;
|
||||||
licenseManagement?: LicenseManagementUIPluginSetup;
|
licenseManagement?: LicenseManagementUIPluginSetup;
|
||||||
home: HomePublicPluginSetup;
|
home?: HomePublicPluginSetup;
|
||||||
embeddable: EmbeddableSetup;
|
embeddable: EmbeddableSetup;
|
||||||
uiActions: UiActionsSetup;
|
uiActions: UiActionsSetup;
|
||||||
kibanaVersion: string;
|
kibanaVersion: string;
|
||||||
|
@ -111,7 +111,9 @@ export class MlPlugin implements Plugin<MlPluginSetup, MlPluginStart> {
|
||||||
const [coreStart] = await core.getStartServices();
|
const [coreStart] = await core.getStartServices();
|
||||||
if (isMlEnabled(license)) {
|
if (isMlEnabled(license)) {
|
||||||
// add ML to home page
|
// add ML to home page
|
||||||
registerFeature(pluginsSetup.home);
|
if (pluginsSetup.home) {
|
||||||
|
registerFeature(pluginsSetup.home);
|
||||||
|
}
|
||||||
|
|
||||||
// register ML for the index pattern management no data screen.
|
// register ML for the index pattern management no data screen.
|
||||||
pluginsSetup.indexPatternManagement.environment.update({
|
pluginsSetup.indexPatternManagement.environment.update({
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import {
|
import {
|
||||||
HomePublicPluginSetup,
|
|
||||||
FeatureCatalogueCategory,
|
FeatureCatalogueCategory,
|
||||||
|
HomePublicPluginSetup,
|
||||||
} from '../../../../src/plugins/home/public';
|
} from '../../../../src/plugins/home/public';
|
||||||
import { PLUGIN_ID } from '../common/constants/app';
|
import { PLUGIN_ID } from '../common/constants/app';
|
||||||
|
|
||||||
|
@ -28,7 +28,22 @@ export const registerFeature = (home: HomePublicPluginSetup) => {
|
||||||
}),
|
}),
|
||||||
icon: 'machineLearningApp',
|
icon: 'machineLearningApp',
|
||||||
path: '/app/ml',
|
path: '/app/ml',
|
||||||
showOnHomePage: true,
|
showOnHomePage: false,
|
||||||
category: FeatureCatalogueCategory.DATA,
|
category: FeatureCatalogueCategory.DATA,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
home.featureCatalogue.register({
|
||||||
|
id: `${PLUGIN_ID}_file_data_visualizer`,
|
||||||
|
title: i18n.translate('xpack.ml.fileDataVisualizerTitle', {
|
||||||
|
defaultMessage: 'Upload a file',
|
||||||
|
}),
|
||||||
|
description: i18n.translate('xpack.ml.fileDataVisualizerDescription', {
|
||||||
|
defaultMessage: 'Import your own CSV, NDJSON, or log file.',
|
||||||
|
}),
|
||||||
|
icon: 'document',
|
||||||
|
path: '/app/ml#/filedatavisualizer',
|
||||||
|
showOnHomePage: true,
|
||||||
|
category: FeatureCatalogueCategory.DATA,
|
||||||
|
order: 520,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -87,7 +87,7 @@ export class MlServerPlugin implements Plugin<MlPluginSetup, MlPluginStart, Plug
|
||||||
order: 500,
|
order: 500,
|
||||||
navLinkId: PLUGIN_ID,
|
navLinkId: PLUGIN_ID,
|
||||||
app: [PLUGIN_ID, 'kibana'],
|
app: [PLUGIN_ID, 'kibana'],
|
||||||
catalogue: [PLUGIN_ID],
|
catalogue: [PLUGIN_ID, `${PLUGIN_ID}_file_data_visualizer`],
|
||||||
management: {
|
management: {
|
||||||
insightsAndAlerting: ['jobsListLink'],
|
insightsAndAlerting: ['jobsListLink'],
|
||||||
},
|
},
|
||||||
|
|
|
@ -54,14 +54,17 @@ export class MonitoringPlugin
|
||||||
if (home) {
|
if (home) {
|
||||||
home.featureCatalogue.register({
|
home.featureCatalogue.register({
|
||||||
id,
|
id,
|
||||||
title,
|
title: i18n.translate('xpack.monitoring.featureCatalogueTitle', {
|
||||||
|
defaultMessage: 'Monitor the stack',
|
||||||
|
}),
|
||||||
icon,
|
icon,
|
||||||
path: '/app/monitoring',
|
path: '/app/monitoring',
|
||||||
showOnHomePage: true,
|
showOnHomePage: true,
|
||||||
category: FeatureCatalogueCategory.ADMIN,
|
category: FeatureCatalogueCategory.ADMIN,
|
||||||
description: i18n.translate('xpack.monitoring.monitoringDescription', {
|
description: i18n.translate('xpack.monitoring.featureCatalogueDescription', {
|
||||||
defaultMessage: 'Track the real-time health and performance of your Elastic Stack.',
|
defaultMessage: 'Track the real-time health and performance of your deployment.',
|
||||||
}),
|
}),
|
||||||
|
order: 610,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
"observability"
|
"observability"
|
||||||
],
|
],
|
||||||
"optionalPlugins": [
|
"optionalPlugins": [
|
||||||
"licensing"
|
"licensing",
|
||||||
|
"home"
|
||||||
],
|
],
|
||||||
"ui": true,
|
"ui": true,
|
||||||
"server": true,
|
"server": true,
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue