diff --git a/.sass-lint.yml b/.sass-lint.yml
index d6eaaf391de1a..9eed50602f520 100644
--- a/.sass-lint.yml
+++ b/.sass-lint.yml
@@ -1,6 +1,7 @@
files:
include:
- 'src/legacy/core_plugins/metrics/**/*.s+(a|c)ss'
+ - 'src/plugins/index_pattern_management/**/*.s+(a|c)ss'
- 'src/plugins/timelion/**/*.s+(a|c)ss'
- 'src/plugins/vis_type_vislib/**/*.s+(a|c)ss'
- 'src/plugins/vis_type_vega/**/*.s+(a|c)ss'
diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md
index a03b1b74fc1ac..842f90b7047c8 100644
--- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md
+++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md
@@ -81,6 +81,7 @@ readonly links: {
readonly loadingData: string;
readonly introduction: string;
};
+ readonly addData: string;
readonly kibana: string;
readonly siem: {
readonly guide: string;
diff --git a/docs/setup/connect-to-elasticsearch.asciidoc b/docs/setup/connect-to-elasticsearch.asciidoc
index bffb3f97cd1b9..f750784c47043 100644
--- a/docs/setup/connect-to-elasticsearch.asciidoc
+++ b/docs/setup/connect-to-elasticsearch.asciidoc
@@ -97,7 +97,7 @@ Using a wildcard is the more popular approach.
comparisons.
+
Kibana reads the index mapping and lists all fields that contain a timestamp. If your
-index doesn't have time-based data, choose *I don't want to use the Time Filter*.
+index doesn't have time-based data, choose *I don't want to use the time filter*.
+
You must select a time field to use global time filters on your dashboards.
diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts
index eb54983d0be13..8853d95181994 100644
--- a/src/core/public/doc_links/doc_links_service.ts
+++ b/src/core/public/doc_links/doc_links_service.ts
@@ -109,6 +109,7 @@ export class DocLinksService {
loadingData: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/tutorial-load-dataset.html`,
introduction: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/index-patterns.html`,
},
+ addData: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/connect-to-elasticsearch.html`,
kibana: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/index.html`,
siem: {
guide: `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/index.html`,
@@ -209,6 +210,7 @@ export interface DocLinksStart {
readonly loadingData: string;
readonly introduction: string;
};
+ readonly addData: string;
readonly kibana: string;
readonly siem: {
readonly guide: string;
diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md
index 9b421e0172df0..0e879d16b4637 100644
--- a/src/core/public/public.api.md
+++ b/src/core/public/public.api.md
@@ -576,6 +576,7 @@ export interface DocLinksStart {
readonly loadingData: string;
readonly introduction: string;
};
+ readonly addData: string;
readonly kibana: string;
readonly siem: {
readonly guide: string;
diff --git a/src/plugins/data/public/index_patterns/index_patterns/redirect_no_index_pattern.tsx b/src/plugins/data/public/index_patterns/index_patterns/redirect_no_index_pattern.tsx
index 7ed6525db6350..ac015f8dd33af 100644
--- a/src/plugins/data/public/index_patterns/index_patterns/redirect_no_index_pattern.tsx
+++ b/src/plugins/data/public/index_patterns/index_patterns/redirect_no_index_pattern.tsx
@@ -40,7 +40,7 @@ export const onRedirectNoIndexPattern = (
const bannerMessage = i18n.translate('data.indexPatterns.ensureDefaultIndexPattern.bannerLabel', {
defaultMessage:
- "In order to visualize and explore data in Kibana, you'll need to create an index pattern to retrieve data from Elasticsearch.",
+ 'To visualize and explore data in Kibana, you must create an index pattern to retrieve data from Elasticsearch.',
});
// Avoid being hostile to new users who don't have an index pattern setup yet
diff --git a/src/plugins/index_pattern_management/public/_templates.scss b/src/plugins/index_pattern_management/public/_templates.scss
new file mode 100644
index 0000000000000..5303537bddabc
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/_templates.scss
@@ -0,0 +1,11 @@
+%inp-empty-state-footer {
+ background: $euiColorLightestShade;
+ margin: 0 (-$euiSizeL) (-$euiSizeL);
+ padding: $euiSizeL;
+ border-radius: 0 0 $euiBorderRadius $euiBorderRadius;
+
+ // sass-lint:disable-block mixins-before-declarations
+ @include euiBreakpoint('xs', 's') {
+ text-align: center;
+ }
+}
diff --git a/src/plugins/index_pattern_management/public/_variables.scss b/src/plugins/index_pattern_management/public/_variables.scss
new file mode 100644
index 0000000000000..5da25a91bd77c
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/_variables.scss
@@ -0,0 +1 @@
+$inpEmptyStateMaxWidth: $euiSizeXXL * 19;
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_prompt/index.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_prompt/index.tsx
deleted file mode 100644
index ab3b90177bcfd..0000000000000
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_prompt/index.tsx
+++ /dev/null
@@ -1,108 +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 {
- EuiDescriptionList,
- EuiDescriptionListDescription,
- EuiDescriptionListTitle,
- EuiFlyout,
- EuiFlyoutBody,
- EuiFlyoutHeader,
- EuiHorizontalRule,
- EuiSpacer,
- EuiText,
-} from '@elastic/eui';
-import { FormattedMessage } from '@kbn/i18n/react';
-import React from 'react';
-
-export const CreateIndexPatternPrompt = ({ onClose }: { onClose: () => void }) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-);
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/__snapshots__/create_index_pattern_wizard.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/__snapshots__/create_index_pattern_wizard.test.tsx.snap
index 6d79515c172fe..0e5fc0582f72c 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/__snapshots__/create_index_pattern_wizard.test.tsx.snap
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/__snapshots__/create_index_pattern_wizard.test.tsx.snap
@@ -62,10 +62,37 @@ exports[`CreateIndexPatternWizard renders index pattern step when there are indi
exports[`CreateIndexPatternWizard renders the empty state when there are no indices 1`] = `
-
+
+
+
+
+
-
+
+
+
+
+
-
- }
- >
-
-
-
- ,
- "learnHowLink":
-
- ,
- "needToIndex":
-
- ,
- }
- }
- />
-
-
-
-
-
-
-`;
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/empty_state.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/empty_state.tsx
deleted file mode 100644
index 43c3bf79026fe..0000000000000
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/empty_state.tsx
+++ /dev/null
@@ -1,90 +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 { EuiCallOut, EuiTextColor, EuiLink, EuiButton } from '@elastic/eui';
-
-import { FormattedMessage } from '@kbn/i18n/react';
-import { IBasePath } from 'kibana/public';
-
-export const EmptyState = ({
- onRefresh,
- prependBasePath,
-}: {
- onRefresh: () => void;
- prependBasePath: IBasePath['prepend'];
-}) => (
-
-
- }
- >
-
-
-
-
- ),
- learnHowLink: (
-
-
-
- ),
- getStartedLink: (
-
-
-
- ),
- }}
- />
-
-
-
-
-
-
-
-);
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/__snapshots__/header.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/__snapshots__/header.test.tsx.snap
index c4f735558b1f2..851e5cc4c2a76 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/__snapshots__/header.test.tsx.snap
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/__snapshots__/header.test.tsx.snap
@@ -7,7 +7,7 @@ exports[`Header should mark the input as invalid 1`] = `
>
@@ -119,7 +119,7 @@ exports[`Header should render normally 1`] = `
>
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/header.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/header.tsx
index f1bf0d54a1cbf..8efa44decf3c6 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/header.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/header.tsx
@@ -66,7 +66,7 @@ export const Header: React.FC = ({
@@ -127,6 +127,7 @@ export const Header: React.FC = ({
id="checkboxShowSystemIndices"
checked={isIncludingSystemIndices}
onChange={onChangeIncludingSystemIndices}
+ data-test-subj="showSystemAndHiddenIndices"
/>
) : null}
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/indices_list/__snapshots__/indices_list.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/indices_list/__snapshots__/indices_list.test.tsx.snap
index 598de4d90e893..6631a9bbd1d02 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/indices_list/__snapshots__/indices_list.test.tsx.snap
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/indices_list/__snapshots__/indices_list.test.tsx.snap
@@ -2,7 +2,10 @@
exports[`IndicesList should change pages 1`] = `
-
+
-
+
-
+
-
+
-
+
-
+
{rows}
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/__snapshots__/loading_indices.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/__snapshots__/loading_indices.test.tsx.snap
index 9d67ca913d415..a5517f6d4b616 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/__snapshots__/loading_indices.test.tsx.snap
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/__snapshots__/loading_indices.test.tsx.snap
@@ -3,47 +3,33 @@
exports[`LoadingIndices should render normally 1`] = `
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
`;
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/loading_indices.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/loading_indices.tsx
index 16e8d1a9f3e98..82603fd598596 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/loading_indices.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/loading_indices.tsx
@@ -19,34 +19,30 @@
import React from 'react';
-import { EuiFlexGroup, EuiFlexItem, EuiText, EuiTextColor, EuiLoadingSpinner } from '@elastic/eui';
+import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiLoadingSpinner } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
export const LoadingIndices = ({ ...rest }) => (
-
+
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
);
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.tsx
index 22b75071b93bb..c2c4c84b51683 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.tsx
@@ -132,7 +132,7 @@ export const StatusMessage: React.FC = ({
/>
);
- } else if (allIndicesLength) {
+ } else {
statusIcon = undefined;
statusColor = 'warning';
statusMessage = (
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx
index fab638509313d..d8555d71d6ec0 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx
@@ -159,7 +159,7 @@ export class StepIndexPattern extends Component indexPatternCreationType.getIndexTags(indexName),
query,
this.state.isIncludingSystemIndices
)
@@ -175,13 +175,13 @@ export class StepIndexPattern extends Component indexPatternCreationType.getIndexTags(indexName),
`${query}*`,
this.state.isIncludingSystemIndices
),
getIndices(
this.context.services.http,
- indexPatternCreationType,
+ (indexName: string) => indexPatternCreationType.getIndexTags(indexName),
query,
this.state.isIncludingSystemIndices
),
@@ -227,7 +227,13 @@ export class StepIndexPattern extends Component ;
+ return (
+ <>
+
+
+
+ >
+ );
}
renderStatusMessage(matchedIndices: {
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/__snapshots__/advanced_options.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/__snapshots__/advanced_options.test.tsx.snap
index d1b10fb532020..a2d2023ea0601 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/__snapshots__/advanced_options.test.tsx.snap
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/__snapshots__/advanced_options.test.tsx.snap
@@ -7,7 +7,7 @@ exports[`AdvancedOptions should hide if not showing 1`] = `
onClick={[Function]}
>
@@ -25,7 +25,7 @@ exports[`AdvancedOptions should render normally 1`] = `
onClick={[Function]}
>
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/advanced_options.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/advanced_options.tsx
index b8f34095743ba..752fcbcd42b5c 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/advanced_options.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/advanced_options.tsx
@@ -45,12 +45,12 @@ export const AdvancedOptions: React.FC = ({
{isVisible ? (
) : (
)}
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/__snapshots__/header.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/__snapshots__/header.test.tsx.snap
index 2ac243780b31d..9efda4fdac7f9 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/__snapshots__/header.test.tsx.snap
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/__snapshots__/header.test.tsx.snap
@@ -17,9 +17,18 @@ exports[`Header should render normally 1`] = `
size="m"
/>
-
- ki*
-
+
+ ki*
+ ,
+ "indexPatternName": "ki*",
+ }
+ }
+ />
`;
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/header.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/header.tsx
index c17b356e159f6..530d0688b61ca 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/header.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/header.tsx
@@ -40,7 +40,14 @@ export const Header: React.FC = ({ indexPattern, indexPatternName }
- {indexPattern}
+ {indexPattern},
+ indexPatternName,
+ }}
+ />
);
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.scss b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.scss
deleted file mode 100644
index 5bd60e8b76afc..0000000000000
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * 1. Bring the line-height down or else this link expands its container when it becomes visible.
- */
-
-.timeFieldRefreshButton {
- line-height: 1 !important; /* 1 */
-}
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.tsx
index 7a3d72551f464..1eae1055ac5ef 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.tsx
@@ -17,8 +17,6 @@
* under the License.
*/
-import './time_field.scss';
-
import React from 'react';
import {
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.test.tsx
index b14cd526d7e27..af5618424bbc0 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.test.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.test.tsx
@@ -27,7 +27,6 @@ jest.mock('./components/step_index_pattern', () => ({ StepIndexPattern: 'StepInd
jest.mock('./components/step_time_field', () => ({ StepTimeField: 'StepTimeField' }));
jest.mock('./components/header', () => ({ Header: 'Header' }));
jest.mock('./components/loading_state', () => ({ LoadingState: 'LoadingState' }));
-jest.mock('./components/empty_state', () => ({ EmptyState: 'EmptyState' }));
jest.mock('./lib/get_indices', () => ({
getIndices: () => {
return [{ name: 'kibana' }];
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx
index cd76ca09ccb74..a789ebbfadbce 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx
@@ -33,7 +33,6 @@ import { StepIndexPattern } from './components/step_index_pattern';
import { StepTimeField } from './components/step_time_field';
import { Header } from './components/header';
import { LoadingState } from './components/loading_state';
-import { EmptyState } from './components/empty_state';
import { context as contextType } from '../../../../kibana_react/public';
import { getCreateBreadcrumbs } from '../breadcrumbs';
@@ -125,7 +124,13 @@ export class CreateIndexPatternWizard extends Component<
// query local and remote indices, updating state independently
ensureMinimumTime(
this.catchAndWarn(
- getIndices(this.context.services.http, this.state.indexPatternCreationType, `*`, false),
+ getIndices(
+ this.context.services.http,
+ (indexName: string) => this.state.indexPatternCreationType.getIndexTags(indexName),
+ `*`,
+ false
+ ),
+
[],
indicesFailMsg
)
@@ -136,7 +141,13 @@ export class CreateIndexPatternWizard extends Component<
this.catchAndWarn(
// if we get an error from remote cluster query, supply fallback value that allows user entry.
// ['a'] is fallback value
- getIndices(this.context.services.http, this.state.indexPatternCreationType, `*:*`, false),
+ getIndices(
+ this.context.services.http,
+ (indexName: string) => this.state.indexPatternCreationType.getIndexTags(indexName),
+ `*:*`,
+ false
+ ),
+
['a'],
clustersFailMsg
).then((remoteIndices: string[] | MatchedItem[]) =>
@@ -200,39 +211,24 @@ export class CreateIndexPatternWizard extends Component<
};
renderHeader() {
+ const { docLinks, indexPatternCreationType } = this.state;
return (
);
}
renderContent() {
- const {
- allIndices,
- isInitiallyLoadingIndices,
- step,
- indexPattern,
- remoteClustersExist,
- } = this.state;
+ const { allIndices, isInitiallyLoadingIndices, step, indexPattern } = this.state;
if (isInitiallyLoadingIndices) {
return ;
}
- const hasDataIndices = allIndices.some(({ name }: MatchedItem) => !name.startsWith('.'));
- if (!hasDataIndices && !remoteClustersExist) {
- return (
-
- );
- }
-
const header = this.renderHeader();
if (step === 1) {
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/extract_time_fields.test.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/extract_time_fields.test.ts
index 4cd28090420a7..8f3765b7b5dcc 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/extract_time_fields.test.ts
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/extract_time_fields.test.ts
@@ -37,7 +37,7 @@ describe('extractTimeFields', () => {
expect(extractTimeFields(fields)).toEqual([
{ display: '@timestamp', fieldName: '@timestamp' },
{ isDisabled: true, display: '───', fieldName: '' },
- { display: `I don't want to use the Time Filter`, fieldName: undefined },
+ { display: `I don't want to use the time filter`, fieldName: undefined },
]);
});
});
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/extract_time_fields.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/extract_time_fields.ts
index b7056ad17343a..efac21245c257 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/extract_time_fields.ts
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/extract_time_fields.ts
@@ -45,7 +45,7 @@ export function extractTimeFields(fields: IFieldType[]) {
const noTimeFieldLabel = i18n.translate(
'indexPatternManagement.createIndexPattern.stepTime.noTimeFieldOptionLabel',
{
- defaultMessage: "I don't want to use the Time Filter",
+ defaultMessage: "I don't want to use the time filter",
}
);
const noTimeFieldOption = {
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_indices.test.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_indices.test.ts
index 8e4dd37284333..44a2d1a3be0d0 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_indices.test.ts
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_indices.test.ts
@@ -18,7 +18,6 @@
*/
import { getIndices, responseToItemArray } from './get_indices';
-import { IndexPatternCreationConfig } from '../../../../../index_pattern_management/public';
import { httpServiceMock } from '../../../../../../core/public/mocks';
import { ResolveIndexResponseItemIndexAttrs } from '../types';
@@ -44,33 +43,27 @@ export const successfulResponse = {
],
};
-const mockIndexPatternCreationType = new IndexPatternCreationConfig({
- type: 'default',
- name: 'name',
- showSystemIndices: false,
- httpClient: {},
- isBeta: false,
-});
+const mockGetTags = () => [];
const http = httpServiceMock.createStartContract();
http.get.mockResolvedValue(successfulResponse);
describe('getIndices', () => {
it('should work in a basic case', async () => {
- const result = await getIndices(http, mockIndexPatternCreationType, 'kibana', false);
+ const result = await getIndices(http, mockGetTags, 'kibana', false);
expect(result.length).toBe(3);
expect(result[0].name).toBe('f-alias');
expect(result[1].name).toBe('foo');
});
it('should ignore ccs query-all', async () => {
- expect((await getIndices(http, mockIndexPatternCreationType, '*:', false)).length).toBe(0);
+ expect((await getIndices(http, mockGetTags, '*:', false)).length).toBe(0);
});
it('should ignore a single comma', async () => {
- expect((await getIndices(http, mockIndexPatternCreationType, ',', false)).length).toBe(0);
- expect((await getIndices(http, mockIndexPatternCreationType, ',*', false)).length).toBe(0);
- expect((await getIndices(http, mockIndexPatternCreationType, ',foobar', false)).length).toBe(0);
+ expect((await getIndices(http, mockGetTags, ',', false)).length).toBe(0);
+ expect((await getIndices(http, mockGetTags, ',*', false)).length).toBe(0);
+ expect((await getIndices(http, mockGetTags, ',foobar', false)).length).toBe(0);
});
it('response object to item array', () => {
@@ -98,8 +91,8 @@ describe('getIndices', () => {
},
],
};
- expect(responseToItemArray(result, mockIndexPatternCreationType)).toMatchSnapshot();
- expect(responseToItemArray({}, mockIndexPatternCreationType)).toEqual([]);
+ expect(responseToItemArray(result, mockGetTags)).toMatchSnapshot();
+ expect(responseToItemArray({}, mockGetTags)).toEqual([]);
});
describe('errors', () => {
@@ -107,7 +100,7 @@ describe('getIndices', () => {
http.get.mockImplementationOnce(() => {
throw new Error('Test error');
});
- const result = await getIndices(http, mockIndexPatternCreationType, 'kibana', false);
+ const result = await getIndices(http, mockGetTags, 'kibana', false);
expect(result.length).toBe(0);
});
});
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_indices.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_indices.ts
index c6a11de1bc4fc..6844e90316e22 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_indices.ts
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_indices.ts
@@ -38,7 +38,7 @@ const frozenLabel = i18n.translate('indexPatternManagement.frozenLabel', {
export async function getIndices(
http: HttpStart,
- indexPatternCreationType: IndexPatternCreationConfig,
+ getIndexTags: IndexPatternCreationConfig['getIndexTags'],
rawPattern: string,
showAllIndices: boolean
): Promise {
@@ -73,7 +73,7 @@ export async function getIndices(
return [];
}
- return responseToItemArray(response, indexPatternCreationType);
+ return responseToItemArray(response, getIndexTags);
} catch {
return [];
}
@@ -81,7 +81,7 @@ export async function getIndices(
export const responseToItemArray = (
response: ResolveIndexResponse,
- indexPatternCreationType: IndexPatternCreationConfig
+ getIndexTags: IndexPatternCreationConfig['getIndexTags']
): MatchedItem[] => {
const source: MatchedItem[] = [];
@@ -89,7 +89,7 @@ export const responseToItemArray = (
const tags: MatchedItem['tags'] = [{ key: 'index', name: indexLabel, color: 'default' }];
const isFrozen = (index.attributes || []).includes(ResolveIndexResponseItemIndexAttrs.FROZEN);
- tags.push(...indexPatternCreationType.getIndexTags(index.name));
+ tags.push(...getIndexTags(index.name));
if (isFrozen) {
tags.push({ name: frozenLabel, key: 'frozen', color: 'danger' });
}
diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx
index 4b538af7c5fe7..987e8f0dae3a0 100644
--- a/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx
+++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx
@@ -27,7 +27,6 @@ import {
EuiBadge,
EuiText,
EuiLink,
- EuiIcon,
EuiCallOut,
EuiPanel,
} from '@elastic/eui';
@@ -162,7 +161,7 @@ export const EditIndexPattern = withRouter(
const timeFilterHeader = i18n.translate(
'indexPatternManagement.editIndexPattern.timeFilterHeader',
{
- defaultMessage: "Time Filter field name: '{timeFieldName}'",
+ defaultMessage: "Time field: '{timeFieldName}'",
values: { timeFieldName: indexPattern.timeFieldName },
}
);
@@ -187,62 +186,55 @@ export const EditIndexPattern = withRouter(
return (
-
-
-
-
- {showTagsSection && (
-
- {Boolean(indexPattern.timeFieldName) && (
-
- {timeFilterHeader}
-
- )}
- {tags.map((tag: any) => (
-
- {tag.name}
-
- ))}
-
+
+
+ {showTagsSection && (
+
+ {Boolean(indexPattern.timeFieldName) && (
+
+ {timeFilterHeader}
+
)}
-
-
-
- {indexPattern.title} }}
- />{' '}
-
- {mappingAPILink}
-
-
-
-
- {conflictedFields.length > 0 && (
-
- {mappingConflictLabel}
-
- )}
-
-
-
-
-
+ {tags.map((tag: any) => (
+
+ {tag.name}
+
+ ))}
+
+ )}
+
+
+
+ {indexPattern.title} }}
+ />{' '}
+
+ {mappingAPILink}
+
+
+
+ {conflictedFields.length > 0 && (
+ <>
+
+
+ {mappingConflictLabel}
+
+ >
+ )}
+
+
);
diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/index_header/index_header.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/index_header/index_header.tsx
index 4cf43d63d5839..8ca8c6453c7e9 100644
--- a/src/plugins/index_pattern_management/public/components/edit_index_pattern/index_header/index_header.tsx
+++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/index_header/index_header.tsx
@@ -19,14 +19,7 @@
import React from 'react';
import { i18n } from '@kbn/i18n';
-import {
- EuiFlexGroup,
- EuiToolTip,
- EuiFlexItem,
- EuiIcon,
- EuiTitle,
- EuiButtonIcon,
-} from '@elastic/eui';
+import { EuiFlexGroup, EuiToolTip, EuiFlexItem, EuiTitle, EuiButtonIcon } from '@elastic/eui';
import { IIndexPattern } from 'src/plugins/data/public';
interface IndexHeaderProps {
@@ -77,22 +70,13 @@ export function IndexHeader({
return (
-
- {defaultIndex === indexPattern.id && (
-
-
-
- )}
-
-
- {indexPattern.title}
-
-
-
+
+ {indexPattern.title}
+
-
- {setDefault && (
+
+ {defaultIndex !== indexPattern.id && setDefault && (
setFieldFilter(e.target.value)}
diff --git a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.scss b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.scss
index 34e8a60d07074..ca230711827dc 100644
--- a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.scss
+++ b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.scss
@@ -1,5 +1,5 @@
.testScript__searchBar {
- .globalQueryBar {
+ .globalQueryBar {
padding: $euiSize 0 0;
}
}
diff --git a/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/__snapshots__/empty_index_pattern_prompt.test.tsx.snap b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/__snapshots__/empty_index_pattern_prompt.test.tsx.snap
new file mode 100644
index 0000000000000..c5e6d1220d8bf
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/__snapshots__/empty_index_pattern_prompt.test.tsx.snap
@@ -0,0 +1,99 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`EmptyIndexPatternPrompt should render normally 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/assets/index_pattern_illustration.scss b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/assets/index_pattern_illustration.scss
new file mode 100644
index 0000000000000..cd0477aba7adf
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/assets/index_pattern_illustration.scss
@@ -0,0 +1,9 @@
+.indexPatternIllustration {
+ &__verticalStripes {
+ fill: $euiColorFullShade;
+ }
+
+ &__dots {
+ fill: $euiColorLightShade;
+ }
+}
diff --git a/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/assets/index_pattern_illustration.tsx b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/assets/index_pattern_illustration.tsx
new file mode 100644
index 0000000000000..2461c0f5df919
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/assets/index_pattern_illustration.tsx
@@ -0,0 +1,551 @@
+/*
+ * 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 './index_pattern_illustration.scss';
+import React from 'react';
+
+const IndexPatternIllustration = () => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+);
+
+export const Illustration = IndexPatternIllustration;
diff --git a/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/empty_index_pattern_prompt.scss b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/empty_index_pattern_prompt.scss
new file mode 100644
index 0000000000000..11ac55b098a57
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/empty_index_pattern_prompt.scss
@@ -0,0 +1,31 @@
+@import '../../../variables';
+@import '../../../templates';
+
+.inpEmptyIndexPatternPrompt {
+ // override EUI specificity
+ max-width: $inpEmptyStateMaxWidth !important; // sass-lint:disable-line no-important
+}
+
+.inpEmptyIndexPatternPrompt__footer {
+ @extend %inp-empty-state-footer;
+ // override EUI specificity
+ align-items: baseline !important; // sass-lint:disable-line no-important
+}
+
+.inpEmptyIndexPatternPrompt__title {
+ // override EUI specificity
+ width: auto !important; // sass-lint:disable-line no-important
+}
+
+@include euiBreakpoint('xs', 's') {
+ .inpEmptyIndexPatternPrompt__illustration > svg {
+ width: $euiSize * 12;
+ height: auto;
+ margin: 0 auto;
+ }
+
+ .inpEmptyIndexPatternPrompt__text {
+ text-align: center;
+ align-items: center;
+ }
+}
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/empty_state.test.tsx b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/empty_index_pattern_prompt.test.tsx
similarity index 57%
rename from src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/empty_state.test.tsx
rename to src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/empty_index_pattern_prompt.test.tsx
index 7fa39363e3ef7..83eb803333afc 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/empty_state.test.tsx
+++ b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/empty_index_pattern_prompt.test.tsx
@@ -18,30 +18,20 @@
*/
import React from 'react';
-import { EmptyState } from '../empty_state';
-import { shallow } from 'enzyme';
-import sinon from 'sinon';
+import { EmptyIndexPatternPrompt } from '../empty_index_pattern_prompt';
+import { shallowWithI18nProvider } from 'test_utils/enzyme_helpers';
-describe('EmptyState', () => {
+describe('EmptyIndexPatternPrompt', () => {
it('should render normally', () => {
- const component = shallow( {}} prependBasePath={(x) => x} />);
+ const component = shallowWithI18nProvider(
+ {} }]}
+ docLinksIndexPatternIntro={'testUrl'}
+ setBreadcrumbs={() => {}}
+ />
+ );
expect(component).toMatchSnapshot();
});
-
- describe('props', () => {
- describe('onRefresh', () => {
- it('is called when refresh button is clicked', () => {
- const onRefreshHandler = sinon.stub();
-
- const component = shallow(
- x} />
- );
-
- component.find('[data-test-subj="refreshIndicesButton"]').simulate('click');
-
- sinon.assert.calledOnce(onRefreshHandler);
- });
- });
- });
});
diff --git a/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/empty_index_pattern_prompt.tsx b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/empty_index_pattern_prompt.tsx
new file mode 100644
index 0000000000000..de389097fd4ba
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/empty_index_pattern_prompt.tsx
@@ -0,0 +1,111 @@
+/*
+ * 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 './empty_index_pattern_prompt.scss';
+
+import React from 'react';
+import { FormattedMessage } from '@kbn/i18n/react';
+
+import { EuiPageContent, EuiSpacer, EuiText, EuiFlexItem, EuiFlexGroup } from '@elastic/eui';
+import { EuiDescriptionListTitle } from '@elastic/eui';
+import { EuiDescriptionListDescription, EuiDescriptionList } from '@elastic/eui';
+import { EuiLink } from '@elastic/eui';
+import { getListBreadcrumbs } from '../../breadcrumbs';
+import { IndexPatternCreationOption } from '../../types';
+import { CreateButton } from '../../create_button';
+import { Illustration } from './assets/index_pattern_illustration';
+import { ManagementAppMountParams } from '../../../../../management/public';
+
+interface Props {
+ canSave: boolean;
+ creationOptions: IndexPatternCreationOption[];
+ docLinksIndexPatternIntro: string;
+ setBreadcrumbs: ManagementAppMountParams['setBreadcrumbs'];
+}
+
+export const EmptyIndexPatternPrompt = ({
+ canSave,
+ creationOptions,
+ docLinksIndexPatternIntro,
+ setBreadcrumbs,
+}: Props) => {
+ setBreadcrumbs(getListBreadcrumbs());
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {canSave && (
+
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/index.tsx b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/index.tsx
new file mode 100644
index 0000000000000..239bb272b23ab
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/index.tsx
@@ -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 { EmptyIndexPatternPrompt } from './empty_index_pattern_prompt';
diff --git a/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_state/__snapshots__/empty_state.test.tsx.snap b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_state/__snapshots__/empty_state.test.tsx.snap
new file mode 100644
index 0000000000000..645694371f905
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_state/__snapshots__/empty_state.test.tsx.snap
@@ -0,0 +1,216 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`EmptyState should render normally 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ icon={
+
+ }
+ onClick={[Function]}
+ title={
+
+ }
+ />
+
+
+
+ }
+ icon={
+
+ }
+ isDisabled={false}
+ onClick={[Function]}
+ title={
+
+ }
+ />
+
+
+
+ }
+ icon={
+
+ }
+ onClick={[Function]}
+ title={
+
+ }
+ />
+
+
+
+
+
+
+
+
+ ,
+ "title": ,
+ },
+ ]
+ }
+ />
+
+
+
+
+
+
+ ,
+ "title": ,
+ },
+ ]
+ }
+ />
+
+
+
+
+
+
+
+
+
+ ,
+ }
+ }
+ />
+
+
+`;
diff --git a/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_state/empty_state.scss b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_state/empty_state.scss
new file mode 100644
index 0000000000000..37889b9d7c483
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_state/empty_state.scss
@@ -0,0 +1,23 @@
+@import '../../../variables';
+@import '../../../templates';
+
+.inpEmptyState {
+ // override EUI specificity
+ max-width: $inpEmptyStateMaxWidth !important; // sass-lint:disable-line no-important
+}
+
+.inpEmptyState__cardGrid {
+ justify-content: center;
+}
+
+.inpEmptyState__card {
+ min-width: $euiSizeXL * 6;
+}
+
+.inpEmptyState__footer {
+ @extend %inp-empty-state-footer;
+}
+
+.inpEmptyState__footerFlexItem {
+ min-width: $euiSizeXL * 7;
+}
diff --git a/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_state/empty_state.test.tsx b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_state/empty_state.test.tsx
new file mode 100644
index 0000000000000..7b2cc0f4c3c60
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_state/empty_state.test.tsx
@@ -0,0 +1,74 @@
+/*
+ * 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 { EmptyState } from '../empty_state';
+import { shallow } from 'enzyme';
+import sinon from 'sinon';
+// @ts-expect-error
+import { findTestSubject } from '@elastic/eui/lib/test';
+import { mountWithIntl } from 'test_utils/enzyme_helpers';
+import { docLinksServiceMock } from '../../../../../../core/public/mocks';
+import { MlCardState } from '../../../types';
+
+const docLinks = docLinksServiceMock.createStartContract();
+
+jest.mock('react-router-dom', () => ({
+ useHistory: () => ({
+ createHref: jest.fn(),
+ }),
+}));
+
+describe('EmptyState', () => {
+ it('should render normally', () => {
+ const component = shallow(
+ {}}
+ navigateToApp={async () => {}}
+ getMlCardState={() => MlCardState.ENABLED}
+ canSave={true}
+ />
+ );
+
+ expect(component).toMatchSnapshot();
+ });
+
+ describe('props', () => {
+ describe('onRefresh', () => {
+ it('is called when refresh button is clicked', () => {
+ const onRefreshHandler = sinon.stub();
+
+ const component = mountWithIntl(
+ {}}
+ getMlCardState={() => MlCardState.ENABLED}
+ canSave={true}
+ />
+ );
+
+ findTestSubject(component, 'refreshIndicesButton').simulate('click');
+
+ sinon.assert.calledOnce(onRefreshHandler);
+ });
+ });
+ });
+});
diff --git a/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_state/empty_state.tsx b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_state/empty_state.tsx
new file mode 100644
index 0000000000000..e758184f0f14b
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_state/empty_state.tsx
@@ -0,0 +1,234 @@
+/*
+ * 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 './empty_state.scss';
+import React from 'react';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
+import { DocLinksStart, ApplicationStart } from 'kibana/public';
+import {
+ EuiPageContentHeader,
+ EuiPageContentHeaderSection,
+ EuiTitle,
+ EuiPageContentBody,
+ EuiPageContent,
+ EuiIcon,
+ EuiSpacer,
+ EuiFlexItem,
+ EuiDescriptionList,
+ EuiFlexGrid,
+ EuiCard,
+ EuiLink,
+ EuiText,
+} from '@elastic/eui';
+import { useHistory } from 'react-router-dom';
+import { reactRouterNavigate } from '../../../../../../plugins/kibana_react/public';
+import { MlCardState } from '../../../types';
+
+export const EmptyState = ({
+ onRefresh,
+ navigateToApp,
+ docLinks,
+ getMlCardState,
+ canSave,
+}: {
+ onRefresh: () => void;
+ navigateToApp: ApplicationStart['navigateToApp'];
+ docLinks: DocLinksStart;
+ getMlCardState: () => MlCardState;
+ canSave: boolean;
+}) => {
+ const mlCard = (
+
+ navigateToApp('ml', { path: '#/filedatavisualizer' })}
+ className="inpEmptyState__card"
+ betaBadgeLabel={
+ getMlCardState() === MlCardState.ENABLED
+ ? undefined
+ : i18n.translate(
+ 'indexPatternManagement.createIndexPattern.emptyState.basicLicenseLabel',
+ {
+ defaultMessage: 'Basic',
+ }
+ )
+ }
+ betaBadgeTooltipContent={i18n.translate(
+ 'indexPatternManagement.createIndexPattern.emptyState.basicLicenseDescription',
+ {
+ defaultMessage: 'This feature requires a Basic license.',
+ }
+ )}
+ isDisabled={getMlCardState() === MlCardState.DISABLED}
+ icon={ }
+ title={
+
+ }
+ description={
+
+ }
+ />
+
+ );
+
+ const createAnyway = (
+
+
+
+
+ ),
+ }}
+ />
+
+ );
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ navigateToApp('home', { path: '#/tutorial_directory' })}
+ icon={ }
+ title={
+
+ }
+ description={
+
+ }
+ />
+
+ {getMlCardState() !== MlCardState.HIDDEN ? mlCard : <>>}
+
+ navigateToApp('home', { path: '#/tutorial_directory/sampleData' })}
+ icon={ }
+ title={
+
+ }
+ description={
+
+ }
+ />
+
+
+
+
+
+
+
+ ),
+ description: (
+
+
+
+ ),
+ },
+ ]}
+ />
+
+
+
+ ),
+ description: (
+
+ {' '}
+
+
+ ),
+ },
+ ]}
+ />
+
+
+
+
+
+
+ {canSave && createAnyway}
+ >
+ );
+};
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/index.ts b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_state/index.ts
similarity index 100%
rename from src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/index.ts
rename to src/plugins/index_pattern_management/public/components/index_pattern_table/empty_state/index.ts
diff --git a/src/plugins/index_pattern_management/public/components/index_pattern_table/index_pattern_table.tsx b/src/plugins/index_pattern_management/public/components/index_pattern_table/index_pattern_table.tsx
index 947882b8df495..2768314a75860 100644
--- a/src/plugins/index_pattern_management/public/components/index_pattern_table/index_pattern_table.tsx
+++ b/src/plugins/index_pattern_management/public/components/index_pattern_table/index_pattern_table.tsx
@@ -20,14 +20,14 @@
import {
EuiBadge,
EuiButtonEmpty,
- EuiButtonIcon,
EuiFlexGroup,
EuiFlexItem,
EuiInMemoryTable,
- EuiPanel,
EuiSpacer,
EuiText,
EuiBadgeGroup,
+ EuiPageContent,
+ EuiTitle,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { withRouter, RouteComponentProps } from 'react-router-dom';
@@ -36,10 +36,13 @@ import { i18n } from '@kbn/i18n';
import { reactRouterNavigate, useKibana } from '../../../../../plugins/kibana_react/public';
import { IndexPatternManagmentContext } from '../../types';
import { CreateButton } from '../create_button';
-import { CreateIndexPatternPrompt } from '../create_index_pattern_prompt';
import { IndexPatternTableItem, IndexPatternCreationOption } from '../types';
import { getIndexPatterns } from '../utils';
import { getListBreadcrumbs } from '../breadcrumbs';
+import { EmptyState } from './empty_state';
+import { MatchedItem, ResolveIndexResponseItemAlias } from '../create_index_pattern_wizard/types';
+import { EmptyIndexPatternPrompt } from './empty_index_pattern_prompt';
+import { getIndices } from '../create_index_pattern_wizard/lib';
const pagination = {
initialPageSize: 10,
@@ -81,13 +84,19 @@ export const IndexPatternTable = ({ canSave, history }: Props) => {
uiSettings,
indexPatternManagementStart,
chrome,
+ docLinks,
+ application,
+ http,
+ getMlCardState,
} = useKibana().services;
- const [showFlyout, setShowFlyout] = useState(false);
const [indexPatterns, setIndexPatterns] = useState([]);
const [creationOptions, setCreationOptions] = useState([]);
+ const [sources, setSources] = useState([]);
+ const [remoteClustersExist, setRemoteClustersExist] = useState(false);
+ const [isLoadingSources, setIsLoadingSources] = useState(true);
+ const [isLoadingIndexPatterns, setIsLoadingIndexPatterns] = useState(true);
setBreadcrumbs(getListBreadcrumbs());
-
useEffect(() => {
(async function () {
const options = await indexPatternManagementStart.creation.getIndexPatternCreationOptions(
@@ -98,9 +107,9 @@ export const IndexPatternTable = ({ canSave, history }: Props) => {
uiSettings.get('defaultIndex'),
indexPatternManagementStart
);
+ setIsLoadingIndexPatterns(false);
setCreationOptions(options);
setIndexPatterns(gettedIndexPatterns);
- setShowFlyout(gettedIndexPatterns.length === 0);
})();
}, [
history.push,
@@ -110,6 +119,28 @@ export const IndexPatternTable = ({ canSave, history }: Props) => {
savedObjects.client,
]);
+ const removeAliases = (item: MatchedItem) =>
+ !((item as unknown) as ResolveIndexResponseItemAlias).indices;
+
+ const loadSources = () => {
+ getIndices(http, () => [], '*', false).then((dataSources) =>
+ setSources(dataSources.filter(removeAliases))
+ );
+ getIndices(http, () => [], '*:*', false).then((dataSources) =>
+ setRemoteClustersExist(!!dataSources.filter(removeAliases).length)
+ );
+ };
+
+ useEffect(() => {
+ getIndices(http, () => [], '*', false).then((dataSources) => {
+ setSources(dataSources.filter(removeAliases));
+ setIsLoadingSources(false);
+ });
+ getIndices(http, () => [], '*:*', false).then((dataSources) =>
+ setRemoteClustersExist(!!dataSources.filter(removeAliases).length)
+ );
+ }, [http, creationOptions]);
+
chrome.docTitle.change(title);
const columns = [
@@ -130,12 +161,11 @@ export const IndexPatternTable = ({ canSave, history }: Props) => {
{name}
+
{index.tags &&
index.tags.map(({ key: tagKey, name: tagName }) => (
-
- {tagName}
-
+ {tagName}
))}
>
@@ -156,31 +186,51 @@ export const IndexPatternTable = ({ canSave, history }: Props) => {
<>>
);
+ if (isLoadingSources || isLoadingIndexPatterns) {
+ return <>>;
+ }
+
+ const hasDataIndices = sources.some(({ name }: MatchedItem) => !name.startsWith('.'));
+
+ if (!indexPatterns.length) {
+ if (!hasDataIndices && !remoteClustersExist) {
+ return (
+
+ );
+ } else {
+ return (
+
+ );
+ }
+ }
+
return (
-
- {showFlyout && setShowFlyout(false)} />}
+
-
-
-
-
- {title}
-
-
-
- setShowFlyout(true)}
- aria-label="Help"
+
+
+ {title}
+
+
+
+
+
-
-
+
+
{createButton}
@@ -195,7 +245,7 @@ export const IndexPatternTable = ({ canSave, history }: Props) => {
sorting={sorting}
search={search}
/>
-
+
);
};
diff --git a/src/plugins/index_pattern_management/public/index.ts b/src/plugins/index_pattern_management/public/index.ts
index 2d6db13757eea..9a0fd39fb4fd9 100644
--- a/src/plugins/index_pattern_management/public/index.ts
+++ b/src/plugins/index_pattern_management/public/index.ts
@@ -41,3 +41,5 @@ export {
IndexPatternCreationOption,
IndexPatternListConfig,
} from './service';
+
+export { MlCardState } from './types';
diff --git a/src/plugins/index_pattern_management/public/management_app/mount_management_section.tsx b/src/plugins/index_pattern_management/public/management_app/mount_management_section.tsx
index bcabd55c87975..add45a07e0c5f 100644
--- a/src/plugins/index_pattern_management/public/management_app/mount_management_section.tsx
+++ b/src/plugins/index_pattern_management/public/management_app/mount_management_section.tsx
@@ -34,7 +34,7 @@ import {
CreateIndexPatternWizardWithRouter,
} from '../components';
import { IndexPatternManagementStartDependencies, IndexPatternManagementStart } from '../plugin';
-import { IndexPatternManagmentContext } from '../types';
+import { IndexPatternManagmentContext, MlCardState } from '../types';
const readOnlyBadge = {
text: i18n.translate('indexPatternManagement.indexPatterns.badge.readOnly.text', {
@@ -48,7 +48,8 @@ const readOnlyBadge = {
export async function mountManagementSection(
getStartServices: StartServicesAccessor,
- params: ManagementAppMountParams
+ params: ManagementAppMountParams,
+ getMlCardState: () => MlCardState
) {
const [
{ chrome, application, savedObjects, uiSettings, notifications, overlays, http, docLinks },
@@ -73,6 +74,7 @@ export async function mountManagementSection(
data,
indexPatternManagementStart: indexPatternManagementStart as IndexPatternManagementStart,
setBreadcrumbs: params.setBreadcrumbs,
+ getMlCardState,
};
ReactDOM.render(
diff --git a/src/plugins/index_pattern_management/public/mocks.ts b/src/plugins/index_pattern_management/public/mocks.ts
index ec8100db42085..6a9ef23e3732e 100644
--- a/src/plugins/index_pattern_management/public/mocks.ts
+++ b/src/plugins/index_pattern_management/public/mocks.ts
@@ -39,6 +39,9 @@ const createSetupContract = (): IndexPatternManagementSetup => ({
getAll: jest.fn(),
getById: jest.fn(),
} as any,
+ environment: {
+ update: jest.fn(),
+ },
});
const createStartContract = (): IndexPatternManagementStart => ({
diff --git a/src/plugins/index_pattern_management/public/plugin.ts b/src/plugins/index_pattern_management/public/plugin.ts
index fe680eff8657e..ee1e00fcafd98 100644
--- a/src/plugins/index_pattern_management/public/plugin.ts
+++ b/src/plugins/index_pattern_management/public/plugin.ts
@@ -86,7 +86,9 @@ export class IndexPatternManagementPlugin
mount: async (params) => {
const { mountManagementSection } = await import('./management_app');
- return mountManagementSection(core.getStartServices, params);
+ return mountManagementSection(core.getStartServices, params, () =>
+ this.indexPatternManagementService.environmentService.getEnvironment().ml()
+ );
},
});
diff --git a/src/plugins/index_pattern_management/public/service/environment/environment.mock.ts b/src/plugins/index_pattern_management/public/service/environment/environment.mock.ts
new file mode 100644
index 0000000000000..2c2c68b8ead2d
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/service/environment/environment.mock.ts
@@ -0,0 +1,44 @@
+/*
+ * 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 { EnvironmentService, EnvironmentServiceSetup } from './environment';
+import { MlCardState } from '../../types';
+
+const createSetupMock = (): jest.Mocked => {
+ const setup = {
+ update: jest.fn(),
+ };
+ return setup;
+};
+
+const createMock = (): jest.Mocked> => {
+ const service = {
+ setup: jest.fn(),
+ getEnvironment: jest.fn(() => ({
+ ml: () => MlCardState.ENABLED,
+ })),
+ };
+ service.setup.mockImplementation(createSetupMock);
+ return service;
+};
+
+export const environmentServiceMock = {
+ createSetup: createSetupMock,
+ create: createMock,
+};
diff --git a/src/plugins/index_pattern_management/public/service/environment/environment.test.ts b/src/plugins/index_pattern_management/public/service/environment/environment.test.ts
new file mode 100644
index 0000000000000..1aa67ba751b81
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/service/environment/environment.test.ts
@@ -0,0 +1,49 @@
+/*
+ * 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 { EnvironmentService } from './environment';
+import { MlCardState } from '../../types';
+
+describe('EnvironmentService', () => {
+ describe('setup', () => {
+ test('allows multiple update calls', () => {
+ const setup = new EnvironmentService().setup();
+ expect(() => {
+ setup.update({ ml: () => MlCardState.ENABLED });
+ }).not.toThrow();
+ });
+ });
+
+ describe('getEnvironment', () => {
+ test('returns default values', () => {
+ const service = new EnvironmentService();
+ expect(service.getEnvironment().ml()).toEqual(MlCardState.DISABLED);
+ });
+
+ test('returns last state of update calls', () => {
+ let cardState = MlCardState.DISABLED;
+ const service = new EnvironmentService();
+ const setup = service.setup();
+ setup.update({ ml: () => cardState });
+ expect(service.getEnvironment().ml()).toEqual(MlCardState.DISABLED);
+ cardState = MlCardState.ENABLED;
+ expect(service.getEnvironment().ml()).toEqual(MlCardState.ENABLED);
+ });
+ });
+});
diff --git a/src/plugins/index_pattern_management/public/service/environment/environment.ts b/src/plugins/index_pattern_management/public/service/environment/environment.ts
new file mode 100644
index 0000000000000..f40ce3589fa76
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/service/environment/environment.ts
@@ -0,0 +1,52 @@
+/*
+ * 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 { MlCardState } from '../../types';
+
+/** @public */
+export interface Environment {
+ /**
+ * Flag whether ml features should be advertised
+ */
+ readonly ml: () => MlCardState;
+}
+
+export class EnvironmentService {
+ private environment = {
+ ml: () => MlCardState.DISABLED,
+ };
+
+ public setup() {
+ return {
+ /**
+ * Update the environment to influence how available features are presented.
+ * @param update
+ */
+ update: (update: Partial) => {
+ this.environment = Object.assign({}, this.environment, update);
+ },
+ };
+ }
+
+ public getEnvironment() {
+ return this.environment;
+ }
+}
+
+export type EnvironmentServiceSetup = ReturnType;
diff --git a/src/plugins/index_pattern_management/public/service/environment/index.ts b/src/plugins/index_pattern_management/public/service/environment/index.ts
new file mode 100644
index 0000000000000..91d14c358e7db
--- /dev/null
+++ b/src/plugins/index_pattern_management/public/service/environment/index.ts
@@ -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 { EnvironmentService, Environment, EnvironmentServiceSetup } from './environment';
diff --git a/src/plugins/index_pattern_management/public/service/index_pattern_management_service.ts b/src/plugins/index_pattern_management/public/service/index_pattern_management_service.ts
index d4cc9c95e76a7..06b9b83b1b601 100644
--- a/src/plugins/index_pattern_management/public/service/index_pattern_management_service.ts
+++ b/src/plugins/index_pattern_management/public/service/index_pattern_management_service.ts
@@ -21,6 +21,7 @@ import { HttpSetup } from '../../../../core/public';
import { IndexPatternCreationManager, IndexPatternCreationConfig } from './creation';
import { IndexPatternListManager, IndexPatternListConfig } from './list';
import { FieldFormatEditors } from './field_format_editors';
+import { EnvironmentService } from './environment';
import {
BytesFormatEditor,
@@ -49,11 +50,13 @@ export class IndexPatternManagementService {
indexPatternCreationManager: IndexPatternCreationManager;
indexPatternListConfig: IndexPatternListManager;
fieldFormatEditors: FieldFormatEditors;
+ environmentService: EnvironmentService;
constructor() {
this.indexPatternCreationManager = new IndexPatternCreationManager();
this.indexPatternListConfig = new IndexPatternListManager();
this.fieldFormatEditors = new FieldFormatEditors();
+ this.environmentService = new EnvironmentService();
}
public setup({ httpClient }: SetupDependencies) {
@@ -83,6 +86,7 @@ export class IndexPatternManagementService {
creation: creationManagerSetup,
list: indexPatternListConfigSetup,
fieldFormatEditors: fieldFormatEditorsSetup,
+ environment: this.environmentService.setup(),
};
}
diff --git a/src/plugins/index_pattern_management/public/types.ts b/src/plugins/index_pattern_management/public/types.ts
index 97941687e652d..2876bd6227350 100644
--- a/src/plugins/index_pattern_management/public/types.ts
+++ b/src/plugins/index_pattern_management/public/types.ts
@@ -44,8 +44,15 @@ export interface IndexPatternManagmentContext {
data: DataPublicPluginStart;
indexPatternManagementStart: IndexPatternManagementStart;
setBreadcrumbs: ManagementAppMountParams['setBreadcrumbs'];
+ getMlCardState: () => MlCardState;
}
export type IndexPatternManagmentContextValue = KibanaReactContextValue<
IndexPatternManagmentContext
>;
+
+export enum MlCardState {
+ HIDDEN,
+ DISABLED,
+ ENABLED,
+}
diff --git a/test/functional/apps/management/_index_patterns_empty.ts b/test/functional/apps/management/_index_patterns_empty.ts
new file mode 100644
index 0000000000000..4ae2e7836ac37
--- /dev/null
+++ b/test/functional/apps/management/_index_patterns_empty.ts
@@ -0,0 +1,66 @@
+/*
+ * 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 { FtrProviderContext } from '../../ftr_provider_context';
+
+export default function ({ getPageObjects, getService }: FtrProviderContext) {
+ const esArchiver = getService('esArchiver');
+ const kibanaServer = getService('kibanaServer');
+ const PageObjects = getPageObjects(['common', 'settings']);
+ const testSubjects = getService('testSubjects');
+ const globalNav = getService('globalNav');
+ const es = getService('legacyEs');
+
+ describe('index pattern empty view', () => {
+ before(async () => {
+ await esArchiver.load('empty_kibana');
+ await kibanaServer.uiSettings.replace({});
+ await PageObjects.settings.navigateTo();
+ });
+
+ after(async () => {
+ await esArchiver.unload('empty_kibana');
+ await esArchiver.loadIfNeeded('makelogs');
+ });
+
+ // create index pattern and return to verify list
+ it(`shows empty views`, async () => {
+ // @ts-expect-error
+ await es.transport.request({
+ path: '/_all',
+ method: 'DELETE',
+ });
+ await PageObjects.settings.clickKibanaIndexPatterns();
+ await testSubjects.existOrFail('createAnyway');
+ // @ts-expect-error
+ await es.transport.request({
+ path: '/logstash-a/_doc',
+ method: 'POST',
+ body: { user: 'matt', message: 20 },
+ });
+ await testSubjects.click('refreshIndicesButton');
+ await testSubjects.existOrFail('createIndexPatternButton', { timeout: 5000 });
+ await PageObjects.settings.createIndexPattern('logstash-*', '');
+ });
+
+ it(`doesn't show read-only badge`, async () => {
+ await globalNav.badgeMissingOrFail();
+ });
+ });
+}
diff --git a/test/functional/apps/management/_kibana_settings.js b/test/functional/apps/management/_kibana_settings.js
index 2a488a94c6889..e2b20bacc0b39 100644
--- a/test/functional/apps/management/_kibana_settings.js
+++ b/test/functional/apps/management/_kibana_settings.js
@@ -28,7 +28,7 @@ export default function ({ getService, getPageObjects }) {
before(async function () {
// delete .kibana index and then wait for Kibana to re-create it
await kibanaServer.uiSettings.replace({});
- await PageObjects.settings.createIndexPattern();
+ await PageObjects.settings.createIndexPattern('logstash-*');
await PageObjects.settings.navigateTo();
});
diff --git a/test/functional/apps/management/index.js b/test/functional/apps/management/index.js
index 97e7314f9678e..d5f0c286af7a5 100644
--- a/test/functional/apps/management/index.js
+++ b/test/functional/apps/management/index.js
@@ -43,6 +43,7 @@ export default function ({ getService, loadTestFile }) {
loadTestFile(require.resolve('./_scripted_fields'));
loadTestFile(require.resolve('./_scripted_fields_preview'));
loadTestFile(require.resolve('./_mgmt_import_saved_objects'));
+ loadTestFile(require.resolve('./_index_patterns_empty'));
});
describe('', function () {
diff --git a/test/functional/page_objects/settings_page.ts b/test/functional/page_objects/settings_page.ts
index 4b80647c8749d..a4285a5f94d51 100644
--- a/test/functional/page_objects/settings_page.ts
+++ b/test/functional/page_objects/settings_page.ts
@@ -55,15 +55,6 @@ export function SettingsPageProvider({ getService, getPageObjects }: FtrProvider
await testSubjects.click('indexPatterns');
await PageObjects.header.waitUntilLoadingHasFinished();
-
- // check for the index pattern info flyout that covers the
- // create index pattern button on smaller screens
- // @ts-ignore
- await retry.waitFor('index pattern info flyout', async () => {
- if (await testSubjects.exists('CreateIndexPatternPrompt')) {
- await testSubjects.click('CreateIndexPatternPrompt > euiFlyoutCloseButton');
- } else return true;
- });
}
async getAdvancedSettings(propertyName: string) {
@@ -311,9 +302,7 @@ export function SettingsPageProvider({ getService, getPageObjects }: FtrProvider
}
async isIndexPatternListEmpty() {
- await testSubjects.existOrFail('indexPatternTable', { timeout: 5000 });
- const indexPatternList = await this.getIndexPatternList();
- return indexPatternList.length === 0;
+ return !(await testSubjects.exists('indexPatternTable', { timeout: 5000 }));
}
async removeLogstashIndexPatternIfExist() {
diff --git a/x-pack/plugins/ml/kibana.json b/x-pack/plugins/ml/kibana.json
index c61db9fb1ad8d..7b4ea5458f4a6 100644
--- a/x-pack/plugins/ml/kibana.json
+++ b/x-pack/plugins/ml/kibana.json
@@ -16,7 +16,8 @@
"share",
"embeddable",
"uiActions",
- "kibanaLegacy"
+ "kibanaLegacy",
+ "indexPatternManagement"
],
"optionalPlugins": [
"security",
diff --git a/x-pack/plugins/ml/public/application/app.tsx b/x-pack/plugins/ml/public/application/app.tsx
index 42c462fa9d869..c281dc4e9ae05 100644
--- a/x-pack/plugins/ml/public/application/app.tsx
+++ b/x-pack/plugins/ml/public/application/app.tsx
@@ -21,7 +21,8 @@ import { MlRouter } from './routing';
import { mlApiServicesProvider } from './services/ml_api_service';
import { HttpService } from './services/http_service';
-export type MlDependencies = Omit & MlStartDependencies;
+export type MlDependencies = Omit &
+ MlStartDependencies;
interface AppProps {
coreStart: CoreStart;
diff --git a/x-pack/plugins/ml/public/plugin.ts b/x-pack/plugins/ml/public/plugin.ts
index aa6163379f9c0..ff59d46de758d 100644
--- a/x-pack/plugins/ml/public/plugin.ts
+++ b/x-pack/plugins/ml/public/plugin.ts
@@ -20,8 +20,10 @@ import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { DataPublicPluginStart } from 'src/plugins/data/public';
import { HomePublicPluginSetup } from 'src/plugins/home/public';
+import { IndexPatternManagementSetup } from 'src/plugins/index_pattern_management/public';
import { EmbeddableSetup } from 'src/plugins/embeddable/public';
import { AppStatus, AppUpdater, DEFAULT_APP_CATEGORIES } from '../../../../src/core/public';
+import { MlCardState } from '../../../../src/plugins/index_pattern_management/public';
import { SecurityPluginSetup } from '../../security/public';
import { LicensingPluginSetup } from '../../licensing/public';
import { registerManagementSection } from './application/management';
@@ -53,6 +55,7 @@ export interface MlSetupDependencies {
uiActions: UiActionsSetup;
kibanaVersion: string;
share: SharePluginSetup;
+ indexPatternManagement: IndexPatternManagementSetup;
}
export type MlCoreSetup = CoreSetup;
@@ -104,11 +107,20 @@ export class MlPlugin implements Plugin {
});
const licensing = pluginsSetup.licensing.license$.pipe(take(1));
- licensing.subscribe((license) => {
+ licensing.subscribe(async (license) => {
+ const [coreStart] = await core.getStartServices();
if (isMlEnabled(license)) {
// add ML to home page
registerFeature(pluginsSetup.home);
+ // register ML for the index pattern management no data screen.
+ pluginsSetup.indexPatternManagement.environment.update({
+ ml: () =>
+ coreStart.application.capabilities.ml.canFindFileStructure
+ ? MlCardState.ENABLED
+ : MlCardState.HIDDEN,
+ });
+
// register various ML plugin features which require a full license
if (isFullLicense(license)) {
registerManagementSection(pluginsSetup.management, core);
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index f2aeed63d6eea..bab0f48c93602 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -2388,11 +2388,6 @@
"indexPatternManagement.createIndexPattern.description": "インデックスパターンは、{single}または{multiple}データソース、{star}と一致します。",
"indexPatternManagement.createIndexPattern.documentation": "ドキュメンテーションを表示",
"indexPatternManagement.createIndexPattern.emptyState.checkDataButton": "新規データを確認",
- "indexPatternManagement.createIndexPattern.emptyStateHeader": "Elasticsearchデータが見つかりませんでした",
- "indexPatternManagement.createIndexPattern.emptyStateLabel.emptyStateDetail": "{needToIndex} {learnHowLink}または{getStartedLink}",
- "indexPatternManagement.createIndexPattern.emptyStateLabel.getStartedLink": "サンプルデータで始めましょう。",
- "indexPatternManagement.createIndexPattern.emptyStateLabel.learnHowLink": "方法を学習",
- "indexPatternManagement.createIndexPattern.emptyStateLabel.needToIndexLabel": "インデックスパターンを作成する前に、Elasticsearchへのデータのインデックスが必要です。",
"indexPatternManagement.createIndexPattern.includeSystemIndicesToggleSwitchLabel": "システムと非表示のインデックスを含める",
"indexPatternManagement.createIndexPattern.loadClustersFailMsg": "リモートクラスターの読み込みに失敗",
"indexPatternManagement.createIndexPattern.loadIndicesFailMsg": "インデックスの読み込みに失敗",
@@ -2403,7 +2398,6 @@
"indexPatternManagement.createIndexPattern.step.indexPatternPlaceholder": "index-name-*",
"indexPatternManagement.createIndexPattern.step.invalidCharactersErrorMessage": "{indexPatternName}にはスペースや{characterList}は使えません。",
"indexPatternManagement.createIndexPattern.step.loadingHeader": "一致するインデックスを検索中…",
- "indexPatternManagement.createIndexPattern.step.loadingLabel": "お待ちください…",
"indexPatternManagement.createIndexPattern.step.nextStepButton": "次のステップ",
"indexPatternManagement.createIndexPattern.step.pagingLabel": "ページごとの行数: {perPage}",
"indexPatternManagement.createIndexPattern.step.status.matchAnyLabel.matchAnyDetail": "インデックスパターンは、{sourceCount, plural, one {個のソース} other {個のソース} }と一致します。",
@@ -2553,15 +2547,6 @@
"indexPatternManagement.indexPattern.sectionsHeader": "インデックスパターン",
"indexPatternManagement.indexPattern.titleExistsLabel": "「{title}」というタイトルのインデックスパターンがすでに存在します。",
"indexPatternManagement.indexPatternList.createButton.betaLabel": "ベータ",
- "indexPatternManagement.indexPatternPrompt.exampleOne": "チャートを作成したりコンテンツを素早くクエリできるように log-west-001 という名前の単一のデータソースをインデックスします。",
- "indexPatternManagement.indexPatternPrompt.exampleOneTitle": "単一のデータソース",
- "indexPatternManagement.indexPatternPrompt.examplesTitle": "インデックスパターンの例",
- "indexPatternManagement.indexPatternPrompt.exampleThree": "比較目的に履歴の動向を集約できるよう、これらのログのアーカイブされた月々のロールアップメトリックスを指定どおりに別々のインデックスパターンにグループ分けします。",
- "indexPatternManagement.indexPatternPrompt.exampleThreeTitle": "カスタムグルーピング",
- "indexPatternManagement.indexPatternPrompt.exampleTwo": "すべての西海岸のサーバーログに対してクエリを実行できるように、頭に「log-west」の付いたすべての受信データソースをグループ化します。",
- "indexPatternManagement.indexPatternPrompt.exampleTwoTitle": "複数データソース",
- "indexPatternManagement.indexPatternPrompt.subtitle": "インデックスパターンは、Kibanaで共有フィールドにクエリを実行できるよう、種類の異なるデータソースをバケットにまとめることができます。",
- "indexPatternManagement.indexPatternPrompt.title": "インデックスパターンについて",
"indexPatternManagement.indexPatterns.badge.readOnly.text": "読み取り専用",
"indexPatternManagement.indexPatterns.badge.readOnly.tooltip": "インデックスパターンを保存できません",
"indexPatternManagement.indexPatterns.createBreadcrumb": "インデックスパターンを作成",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 82a6b128ad619..ab4538be02c48 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -2389,11 +2389,6 @@
"indexPatternManagement.createIndexPattern.description": "索引模式可以匹配单个源,例如 {single} 或 {multiple} 个数据源、{star}。",
"indexPatternManagement.createIndexPattern.documentation": "阅读文档",
"indexPatternManagement.createIndexPattern.emptyState.checkDataButton": "检查新数据",
- "indexPatternManagement.createIndexPattern.emptyStateHeader": "找不到任何 Elasticsearch 数据",
- "indexPatternManagement.createIndexPattern.emptyStateLabel.emptyStateDetail": "{needToIndex}{learnHowLink}或{getStartedLink}",
- "indexPatternManagement.createIndexPattern.emptyStateLabel.getStartedLink": "开始使用一些样例数据集。",
- "indexPatternManagement.createIndexPattern.emptyStateLabel.learnHowLink": "了解操作方法",
- "indexPatternManagement.createIndexPattern.emptyStateLabel.needToIndexLabel": "您需要在 Elasticsearch 中索引一些数据后,才能创建索引模式。",
"indexPatternManagement.createIndexPattern.includeSystemIndicesToggleSwitchLabel": "包括系统和隐藏索引",
"indexPatternManagement.createIndexPattern.loadClustersFailMsg": "无法加载远程集群",
"indexPatternManagement.createIndexPattern.loadIndicesFailMsg": "无法加载索引",
@@ -2404,7 +2399,6 @@
"indexPatternManagement.createIndexPattern.step.indexPatternPlaceholder": "index-name-*",
"indexPatternManagement.createIndexPattern.step.invalidCharactersErrorMessage": "{indexPatternName} 不能包含空格或字符:{characterList}",
"indexPatternManagement.createIndexPattern.step.loadingHeader": "正在寻找匹配的索引......",
- "indexPatternManagement.createIndexPattern.step.loadingLabel": "请稍候......",
"indexPatternManagement.createIndexPattern.step.nextStepButton": "下一步",
"indexPatternManagement.createIndexPattern.step.pagingLabel": "每页行数:{perPage}",
"indexPatternManagement.createIndexPattern.step.status.matchAnyLabel.matchAnyDetail": "您的索引模式可以匹配{sourceCount, plural, one {您的 # 个源} other {您的 # 个源中的任何一个} }。",
@@ -2554,15 +2548,6 @@
"indexPatternManagement.indexPattern.sectionsHeader": "索引模式",
"indexPatternManagement.indexPattern.titleExistsLabel": "具有标题“{title}”的索引模式已存在。",
"indexPatternManagement.indexPatternList.createButton.betaLabel": "公测版",
- "indexPatternManagement.indexPatternPrompt.exampleOne": "索引单个称作 log-west-001 的数据源,以便可以快速地构建图表或查询其内容。",
- "indexPatternManagement.indexPatternPrompt.exampleOneTitle": "单数据源",
- "indexPatternManagement.indexPatternPrompt.examplesTitle": "索引模式示例",
- "indexPatternManagement.indexPatternPrompt.exampleThree": "具体而言,将这些日志每月存档的汇总/打包指标分组成不同的索引模式,从而可以聚合历史趋势以进行比较。",
- "indexPatternManagement.indexPatternPrompt.exampleThreeTitle": "定制分组",
- "indexPatternManagement.indexPatternPrompt.exampleTwo": "分组以 log-west* 开头的所有传入数据源,以便可以查询所有西海岸服务器日志。",
- "indexPatternManagement.indexPatternPrompt.exampleTwoTitle": "多数据源",
- "indexPatternManagement.indexPatternPrompt.subtitle": "索引模式允许您将异类的数据源一起装入存储桶,从而可以在 Kibana 中查询它们共享的字段。",
- "indexPatternManagement.indexPatternPrompt.title": "关于索引模式",
"indexPatternManagement.indexPatterns.badge.readOnly.text": "只读",
"indexPatternManagement.indexPatterns.badge.readOnly.tooltip": "无法保存索引模式",
"indexPatternManagement.indexPatterns.createBreadcrumb": "创建索引模式",
diff --git a/x-pack/test/functional/apps/index_patterns/feature_controls/index_patterns_security.ts b/x-pack/test/functional/apps/index_patterns/feature_controls/index_patterns_security.ts
index bc36f70df3641..cedd96f147c2b 100644
--- a/x-pack/test/functional/apps/index_patterns/feature_controls/index_patterns_security.ts
+++ b/x-pack/test/functional/apps/index_patterns/feature_controls/index_patterns_security.ts
@@ -130,7 +130,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
it(`index pattern listing doesn't show create button`, async () => {
await PageObjects.settings.clickKibanaIndexPatterns();
- await testSubjects.existOrFail('indexPatternTable');
+ await testSubjects.existOrFail('emptyIndexPatternPrompt');
await testSubjects.missingOrFail('createIndexPatternButton');
});