diff --git a/package.json b/package.json
index 0cf2676cdc172..510dcfaf8081a 100644
--- a/package.json
+++ b/package.json
@@ -211,6 +211,7 @@
"@kbn/shared-ux-avatar-solution": "link:bazel-bin/packages/shared-ux/avatar/solution",
"@kbn/shared-ux-button-exit-full-screen": "link:bazel-bin/packages/shared-ux/button/exit_full_screen",
"@kbn/shared-ux-button-toolbar": "link:bazel-bin/packages/shared-ux/button_toolbar",
+ "@kbn/shared-ux-card-no-data": "link:bazel-bin/packages/shared-ux/card/no_data",
"@kbn/shared-ux-components": "link:bazel-bin/packages/kbn-shared-ux-components",
"@kbn/shared-ux-link-redirect-app": "link:bazel-bin/packages/shared-ux/link/redirect_app",
"@kbn/shared-ux-page-analytics-no-data": "link:bazel-bin/packages/shared-ux/page/analytics_no_data",
@@ -751,6 +752,7 @@
"@types/kbn__shared-ux-avatar-solution": "link:bazel-bin/packages/shared-ux/avatar/solution/npm_module_types",
"@types/kbn__shared-ux-button-exit-full-screen": "link:bazel-bin/packages/shared-ux/button/exit_full_screen/npm_module_types",
"@types/kbn__shared-ux-button-toolbar": "link:bazel-bin/packages/shared-ux/button_toolbar/npm_module_types",
+ "@types/kbn__shared-ux-card-no-data": "link:bazel-bin/packages/shared-ux/card/no_data/npm_module_types",
"@types/kbn__shared-ux-components": "link:bazel-bin/packages/kbn-shared-ux-components/npm_module_types",
"@types/kbn__shared-ux-link-redirect-app": "link:bazel-bin/packages/shared-ux/link/redirect_app/npm_module_types",
"@types/kbn__shared-ux-page-analytics-no-data": "link:bazel-bin/packages/shared-ux/page/analytics_no_data/npm_module_types",
diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel
index cc5c0e13dcccf..6c65af1a97e91 100644
--- a/packages/BUILD.bazel
+++ b/packages/BUILD.bazel
@@ -146,6 +146,7 @@ filegroup(
"//packages/shared-ux/avatar/solution:build",
"//packages/shared-ux/button_toolbar:build",
"//packages/shared-ux/button/exit_full_screen:build",
+ "//packages/shared-ux/card/no_data:build",
"//packages/shared-ux/link/redirect_app:build",
"//packages/shared-ux/page/analytics_no_data:build",
"//packages/shared-ux/page/kibana_no_data:build",
@@ -279,6 +280,7 @@ filegroup(
"//packages/shared-ux/avatar/solution:build_types",
"//packages/shared-ux/button_toolbar:build_types",
"//packages/shared-ux/button/exit_full_screen:build_types",
+ "//packages/shared-ux/card/no_data:build_types",
"//packages/shared-ux/link/redirect_app:build_types",
"//packages/shared-ux/page/analytics_no_data:build_types",
"//packages/shared-ux/page/kibana_no_data:build_types",
diff --git a/packages/kbn-shared-ux-components/BUILD.bazel b/packages/kbn-shared-ux-components/BUILD.bazel
index 1a4a7100ded72..20d71557fef9a 100644
--- a/packages/kbn-shared-ux-components/BUILD.bazel
+++ b/packages/kbn-shared-ux-components/BUILD.bazel
@@ -45,6 +45,7 @@ RUNTIME_DEPS = [
"//packages/shared-ux/avatar/solution",
"//packages/shared-ux/link/redirect_app",
"//packages/shared-ux/prompt/no_data_views",
+ "//packages/shared-ux/card/no_data",
"//packages/kbn-shared-ux-services",
"//packages/kbn-shared-ux-storybook",
"//packages/kbn-shared-ux-utility",
@@ -74,6 +75,7 @@ TYPES_DEPS = [
"//packages/shared-ux/avatar/solution:npm_module_types",
"//packages/shared-ux/link/redirect_app:npm_module_types",
"//packages/shared-ux/prompt/no_data_views:npm_module_types",
+ "//packages/shared-ux/card/no_data:npm_module_types",
"//packages/kbn-shared-ux-services:npm_module_types",
"//packages/kbn-shared-ux-storybook:npm_module_types",
"//packages/kbn-shared-ux-utility:npm_module_types",
diff --git a/packages/kbn-shared-ux-components/src/page_template/index.ts b/packages/kbn-shared-ux-components/src/page_template/index.ts
index 671f720972fc9..cd7d6232d9a8b 100644
--- a/packages/kbn-shared-ux-components/src/page_template/index.ts
+++ b/packages/kbn-shared-ux-components/src/page_template/index.ts
@@ -5,7 +5,7 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
-export { NoDataCard, ElasticAgentCard, NoDataPage, NoDataConfigPage } from './no_data_page';
+export { NoDataPage, NoDataConfigPage } from './no_data_page';
export { KibanaPageTemplate } from './page_template';
export type { KibanaPageTemplateProps } from './types';
export type { NoDataPageProps } from './no_data_page';
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/__snapshots__/no_data_page.test.tsx.snap b/packages/kbn-shared-ux-components/src/page_template/no_data_page/__snapshots__/no_data_page.test.tsx.snap
deleted file mode 100644
index 5fd29bc57b331..0000000000000
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/__snapshots__/no_data_page.test.tsx.snap
+++ /dev/null
@@ -1,55 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`NoDataPage render 1`] = `
-
-
-
-
-
- Welcome to Elastic Analytics!
-
-
-
-
-
- ,
- "solution": "Analytics",
- }
- }
- />
-
-
-
-
-
-
-`;
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/index.ts b/packages/kbn-shared-ux-components/src/page_template/no_data_page/index.ts
index 894097727cd1f..a6f8c91f7614c 100644
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/index.ts
+++ b/packages/kbn-shared-ux-components/src/page_template/no_data_page/index.ts
@@ -6,7 +6,6 @@
* Side Public License, v 1.
*/
-export { NoDataCard, ElasticAgentCard } from './no_data_card';
export { NoDataPage } from './no_data_page';
export type { NoDataPageProps } from './types';
export { NoDataConfigPage, NoDataConfigPageWithSolutionNavBar } from './no_data_config_page';
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.component.test.tsx.snap b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.component.test.tsx.snap
deleted file mode 100644
index c871196b92282..0000000000000
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.component.test.tsx.snap
+++ /dev/null
@@ -1,104 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`ElasticAgentCardComponent props button 1`] = `
-
- }
- title="Add Elastic Agent"
-/>
-`;
-
-exports[`ElasticAgentCardComponent props href 1`] = `
-
- }
- title="Add Elastic Agent"
-/>
-`;
-
-exports[`ElasticAgentCardComponent renders 1`] = `
-
- }
- title="Add Elastic Agent"
-/>
-`;
-
-exports[`ElasticAgentCardComponent renders with canAccessFleet false 1`] = `
-
- This integration is not yet enabled. Your administrator has the required permissions to turn it on.
-
- }
- image={
-
- }
- isDisabled={true}
- title={
-
- Contact your administrator
-
- }
-/>
-`;
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap
deleted file mode 100644
index dbdb652a10c1f..0000000000000
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap
+++ /dev/null
@@ -1,75 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`ElasticAgentCard renders 1`] = `
-
-
-
-
-
-
-
-
-
-
-
-
-
- Add Elastic Agent
-
-
-
-
-
- Use Elastic Agent for a simple, unified way to collect data from your machines.
-
-
-
-
-
-
-`;
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/__snapshots__/no_data_card.test.tsx.snap b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/__snapshots__/no_data_card.test.tsx.snap
deleted file mode 100644
index 0028d505e9187..0000000000000
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/__snapshots__/no_data_card.test.tsx.snap
+++ /dev/null
@@ -1,231 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`NoDataCard props button 1`] = `
-
-`;
-
-exports[`NoDataCard props extends EuiCardProps 1`] = `
-
-`;
-
-exports[`NoDataCard props href 1`] = `
-
-`;
-
-exports[`NoDataCard props isDisabled 1`] = `
-
-
-
-
-
-
-
-
-`;
-
-exports[`NoDataCard renders 1`] = `
-
-`;
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.component.test.tsx b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.component.test.tsx
deleted file mode 100644
index 367fcd10b96a9..0000000000000
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.component.test.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { shallow } from 'enzyme';
-import React from 'react';
-import { ElasticAgentCardComponent } from './elastic_agent_card.component';
-import { NoDataCard } from './no_data_card';
-
-describe('ElasticAgentCardComponent', () => {
- test('renders', () => {
- const component = shallow();
- expect(component).toMatchSnapshot();
- });
-
- test('renders with canAccessFleet false', () => {
- const component = shallow();
- expect(component.find(NoDataCard).props().isDisabled).toBe(true);
- expect(component).toMatchSnapshot();
- });
-
- describe('props', () => {
- test('button', () => {
- const component = shallow(
-
- );
- expect(component.find(NoDataCard).props().button).toBe('Button');
- expect(component).toMatchSnapshot();
- });
-
- test('href', () => {
- const component = shallow(
-
- );
- expect(component.find(NoDataCard).props().href).toBe('some path');
- expect(component).toMatchSnapshot();
- });
- });
-});
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.component.tsx b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.component.tsx
deleted file mode 100644
index 31d0aad7cc631..0000000000000
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.component.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import React, { FunctionComponent } from 'react';
-import { i18n } from '@kbn/i18n';
-import { EuiImage, EuiTextColor } from '@elastic/eui';
-import { ElasticAgentCardProps } from './types';
-import { NoDataCard } from './no_data_card';
-import ElasticAgentCardIllustration from './assets/elastic_agent_card.svg';
-
-export type ElasticAgentCardComponentProps = ElasticAgentCardProps & {
- canAccessFleet: boolean;
-};
-
-const noPermissionTitle = i18n.translate(
- 'sharedUXComponents.noDataPage.elasticAgentCard.noPermission.title',
- {
- defaultMessage: `Contact your administrator`,
- }
-);
-
-const noPermissionDescription = i18n.translate(
- 'sharedUXComponents.noDataPage.elasticAgentCard.noPermission.description',
- {
- defaultMessage: `This integration is not yet enabled. Your administrator has the required permissions to turn it on.`,
- }
-);
-
-const elasticAgentCardTitle = i18n.translate(
- 'sharedUXComponents.noDataPage.elasticAgentCard.title',
- {
- defaultMessage: 'Add Elastic Agent',
- }
-);
-
-const elasticAgentCardDescription = i18n.translate(
- 'sharedUXComponents.noDataPage.elasticAgentCard.description',
- {
- defaultMessage: `Use Elastic Agent for a simple, unified way to collect data from your machines.`,
- }
-);
-
-/**
- * Creates a specific NoDataCard pointing users to Integrations when `canAccessFleet`
- */
-export const ElasticAgentCardComponent: FunctionComponent = ({
- canAccessFleet,
- title = elasticAgentCardTitle,
- description,
- ...cardRest
-}) => {
- const props = canAccessFleet
- ? {
- title,
- description: description || elasticAgentCardDescription,
- }
- : {
- title: {noPermissionTitle},
- description: {noPermissionDescription},
- isDisabled: true,
- };
-
- const image = (
-
- );
-
- return ;
-};
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.stories.tsx b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.stories.tsx
deleted file mode 100644
index a87da6ff9ca0e..0000000000000
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.stories.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import React from 'react';
-
-import {
- ElasticAgentCardComponent as Component,
- ElasticAgentCardComponentProps as ComponentProps,
-} from './elastic_agent_card.component';
-
-import { ElasticAgentCard } from './elastic_agent_card';
-
-export default {
- title: 'Page Template/No Data/Elastic Agent Data Card',
- description: 'A solution-specific wrapper around NoDataCard, to be used on NoData page',
-};
-
-type Params = Pick;
-
-export const PureComponent = (params: Params) => {
- return ;
-};
-
-PureComponent.argTypes = {
- canAccessFleet: {
- control: 'boolean',
- defaultValue: true,
- },
- description: {
- control: 'text',
- defaultValue: '',
- },
-};
-
-export const ConnectedComponent = () => {
- return ;
-};
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.test.tsx b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.test.tsx
deleted file mode 100644
index ed0b4471fa32c..0000000000000
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.test.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { ReactWrapper } from 'enzyme';
-import React from 'react';
-import { mountWithIntl } from '@kbn/test-jest-helpers';
-import {
- SharedUxServicesProvider,
- SharedUxServices,
- mockServicesFactory,
-} from '@kbn/shared-ux-services';
-
-import { ElasticAgentCard } from './elastic_agent_card';
-import { ElasticAgentCardComponent } from './elastic_agent_card.component';
-
-describe('ElasticAgentCard', () => {
- let services: SharedUxServices;
- let mount: (element: JSX.Element) => ReactWrapper;
-
- beforeEach(() => {
- services = mockServicesFactory();
- mount = (element: JSX.Element) =>
- mountWithIntl({element});
- });
-
- afterEach(() => {
- jest.resetAllMocks();
- });
-
- test('renders', () => {
- const component = mount();
- expect(component.render()).toMatchSnapshot();
- });
-
- describe('href', () => {
- test('returns href if href is given', () => {
- const component = mount();
- expect(component.find(ElasticAgentCardComponent).props().href).toBe('/take/me/somewhere');
- });
-
- test('returns prefix + category if href is not given', () => {
- const component = mount();
- expect(component.find(ElasticAgentCardComponent).props().href).toBe(
- '/app/integrations/browse/solutions'
- );
- });
-
- test('returns prefix if nor category nor href are given', () => {
- const component = mount();
- expect(component.find(ElasticAgentCardComponent).props().href).toBe(
- '/app/integrations/browse'
- );
- });
- });
-
- describe('description', () => {
- test('renders custom description if provided', () => {
- const component = mount(
-
- );
- expect(component.find(ElasticAgentCardComponent).props().description).toBe(
- 'Build seamless search experiences faster.'
- );
- });
- });
-
- describe('canAccessFleet', () => {
- test('passes in the right parameter', () => {
- const component = mount();
- expect(component.find(ElasticAgentCardComponent).props().canAccessFleet).toBe(true);
- });
- });
-});
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.tsx b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.tsx
deleted file mode 100644
index a4025f33616ed..0000000000000
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import React, { useMemo } from 'react';
-import { useApplication, useHttp, usePermissions } from '@kbn/shared-ux-services';
-import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app';
-import useObservable from 'react-use/lib/useObservable';
-
-import { ElasticAgentCardProps } from './types';
-import { ElasticAgentCardComponent } from './elastic_agent_card.component';
-
-export const ElasticAgentCard = (props: ElasticAgentCardProps) => {
- const { canAccessFleet } = usePermissions();
- const { addBasePath } = useHttp();
- const { navigateToUrl, currentAppId$ } = useApplication();
- const currentAppId = useObservable(currentAppId$);
-
- const { href: srcHref, category, description } = props;
-
- const href = useMemo(() => {
- if (srcHref) {
- return srcHref;
- }
-
- // TODO: get this URL from a locator
- const prefix = '/app/integrations/browse';
-
- if (category) {
- return addBasePath(`${prefix}/${category}`);
- }
-
- return addBasePath(prefix);
- }, [addBasePath, srcHref, category]);
-
- return (
-
-
-
- );
-};
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.stories.tsx b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.stories.tsx
deleted file mode 100644
index 9c1b2d0322074..0000000000000
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.stories.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import React from 'react';
-import { NoDataCard } from './no_data_card';
-import type { NoDataCardProps } from './types';
-
-export default {
- title: 'Page Template/No Data/No Data Card',
- description: 'A wrapper around EuiCard, to be used on NoData page',
-};
-
-type Params = Pick;
-
-export const PureComponent = (params: Params) => {
- return ;
-};
-
-PureComponent.argTypes = {
- button: {
- control: {
- type: 'text',
- },
- defaultValue: 'Button text',
- },
- description: {
- control: {
- type: 'text',
- },
- defaultValue: 'This is a description',
- },
-};
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.tsx b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.tsx
deleted file mode 100644
index 508d03d5028b8..0000000000000
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { i18n } from '@kbn/i18n';
-import React, { FunctionComponent } from 'react';
-import { EuiButton, EuiCard, EuiScreenReaderOnly } from '@elastic/eui';
-
-import type { NoDataCardProps } from './types';
-import { NoDataCardStyles } from './no_data_card.styles';
-
-const defaultDescription = i18n.translate(
- 'sharedUXComponents.pageTemplate.noDataCard.description',
- {
- defaultMessage: `Proceed without collecting data`,
- }
-);
-
-export const NoDataCard: FunctionComponent = ({
- title: titleProp,
- button,
- description,
- isDisabled,
- ...cardRest
-}) => {
- const styles = NoDataCardStyles();
-
- const footer = () => {
- // Don't render the footer action if disabled
- if (isDisabled) {
- return;
- }
- // Render a custom footer action if the button is not a simple string
- if (button && typeof button !== 'string') {
- return button;
- }
- // Default footer action is a button with the provided or default string
- return {button || titleProp};
- };
-
- const cardDescription = description || defaultDescription;
-
- // Fix the need for an a11y title even though the button exists by setting to screen reader only
- const title = titleProp ? (
-
- {titleProp}
-
- ) : null;
-
- return (
-
- );
-};
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/types.ts b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/types.ts
deleted file mode 100644
index fef4f654ce970..0000000000000
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/types.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { EuiCardProps } from '@elastic/eui';
-import { MouseEventHandler, ReactNode } from 'react';
-
-export type NoDataCardProps = Partial> & {
- /**
- * Provide just a string for the button's label, or a whole component;
- * The button will be hidden completely if `isDisabled=true`
- */
- button?: string | ReactNode;
- /**
- * Remapping `onClick` to any element
- */
- onClick?: MouseEventHandler;
- /**
- * Description for the card;
- * If not provided, the default will be used
- */
- description?: string | ReactNode;
-};
-
-export type ElasticAgentCardProps = NoDataCardProps & {
- /**
- * Category to auto-select within Fleet
- */
- category?: string;
-};
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_page.test.tsx b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_page.test.tsx
index c84dea27552aa..b9474285469e1 100644
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_page.test.tsx
+++ b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_page.test.tsx
@@ -7,24 +7,27 @@
*/
import React from 'react';
+import { mountWithIntl } from '@kbn/test-jest-helpers';
+import { NoDataCard } from '@kbn/shared-ux-card-no-data';
+import { SharedUxServicesProvider, mockServicesFactory } from '@kbn/shared-ux-services';
+
import { NoDataPage } from './no_data_page';
-import { shallowWithIntl } from '@kbn/test-jest-helpers';
-import { ElasticAgentCard } from './no_data_card';
describe('NoDataPage', () => {
test('render', () => {
- const component = shallowWithIntl(
-
+ const component = mountWithIntl(
+
+
+
);
- expect(component).toMatchSnapshot();
expect(component.find('h1').html()).toContain('Welcome to Elastic Analytics!');
- expect(component.find(ElasticAgentCard).length).toBe(1);
+ expect(component.find(NoDataCard).length).toBe(1);
});
});
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_page.tsx b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_page.tsx
index 093a76d17759f..724570d4baccd 100644
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_page.tsx
+++ b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_page.tsx
@@ -7,6 +7,7 @@
*/
import React, { useMemo, FunctionComponent } from 'react';
+import useObservable from 'react-use/lib/useObservable';
import classNames from 'classnames';
import { EuiLink, EuiSpacer, EuiText, EuiTextColor } from '@elastic/eui';
@@ -14,7 +15,8 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { KibanaSolutionAvatar } from '@kbn/shared-ux-avatar-solution';
-import { ElasticAgentCard } from './no_data_card';
+import { useSharedUxServices } from '@kbn/shared-ux-services';
+import { NoDataCard, NoDataCardProvider } from '@kbn/shared-ux-card-no-data';
import { NoDataPageProps } from './types';
export const NoDataPage: FunctionComponent = ({
@@ -25,6 +27,19 @@ export const NoDataPage: FunctionComponent = ({
pageTitle,
...rest
}) => {
+ const services = useSharedUxServices();
+
+ // TODO: clintandrewhall - including the `NoDataCardProvider` here is a temporary solution
+ // to consumers using this context to populate the NoDataPage. This will likely be removed soon,
+ // when NoDataPage is moved to its own package.
+ const currentAppId = useObservable(services.application.currentAppId$);
+ const noDataCardServices = {
+ currentAppId,
+ addBasePath: services.http.addBasePath,
+ canAccessFleet: services.permissions.canAccessFleet,
+ navigateToUrl: services.application.navigateToUrl,
+ };
+
const actionKeys = Object.keys(action);
const actionCard = useMemo(() => {
@@ -34,7 +49,7 @@ export const NoDataPage: FunctionComponent = ({
const actionKey = actionKeys[0];
const key =
actionKey === 'elasticAgent' ? 'empty-page-agent-action' : `empty-page-${actionKey}-action`;
- return ;
+ return ;
}, [action, actionKeys]);
const title =
@@ -74,7 +89,7 @@ export const NoDataPage: FunctionComponent = ({
- {actionCard}
+ {actionCard}
);
};
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/types.ts b/packages/kbn-shared-ux-components/src/page_template/no_data_page/types.ts
index b304a1462a278..e22f7a7b81a77 100644
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/types.ts
+++ b/packages/kbn-shared-ux-components/src/page_template/no_data_page/types.ts
@@ -7,9 +7,9 @@
*/
import { CommonProps } from '@elastic/eui';
-import { ElasticAgentCardProps } from './no_data_card';
+import { NoDataCardProps } from '@kbn/shared-ux-card-no-data';
-export type NoDataPageActions = ElasticAgentCardProps;
+export type NoDataPageActions = NoDataCardProps;
export interface NoDataPageProps extends CommonProps {
/**
diff --git a/packages/kbn-shared-ux-storybook/src/config/main.ts b/packages/kbn-shared-ux-storybook/src/config/main.ts
index ccd0d1e73cba8..6e57ca8ad5e72 100644
--- a/packages/kbn-shared-ux-storybook/src/config/main.ts
+++ b/packages/kbn-shared-ux-storybook/src/config/main.ts
@@ -15,4 +15,7 @@ module.exports = {
'../../../kbn-shared-ux*/**/*.stories.+(tsx|mdx)',
'../../../../src/plugins/shared_ux/**/*.stories.+(tsx|mdx)',
],
+ reactOptions: {
+ strictMode: true,
+ },
};
diff --git a/packages/shared-ux/card/no_data/BUILD.bazel b/packages/shared-ux/card/no_data/BUILD.bazel
new file mode 100644
index 0000000000000..ae3e21ba55247
--- /dev/null
+++ b/packages/shared-ux/card/no_data/BUILD.bazel
@@ -0,0 +1,143 @@
+load("@npm//@bazel/typescript:index.bzl", "ts_config")
+load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
+load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
+
+PKG_DIRNAME = "no_data"
+PKG_REQUIRE_NAME = "@kbn/shared-ux-card-no-data"
+
+SOURCE_FILES = glob(
+ [
+ "src/**/*.ts",
+ "src/**/*.tsx",
+ "src/**/*.mdx",
+ "src/**/*.svg",
+ ],
+ exclude = [
+ "**/*.test.*",
+ ],
+)
+
+SRCS = SOURCE_FILES
+
+filegroup(
+ name = "srcs",
+ srcs = SRCS,
+)
+
+NPM_MODULE_EXTRA_FILES = [
+ "package.json",
+]
+
+# In this array place runtime dependencies, including other packages and NPM packages
+# which must be available for this code to run.
+#
+# To reference other packages use:
+# "//repo/relative/path/to/package"
+# eg. "//packages/kbn-utils"
+#
+# To reference a NPM package use:
+# "@npm//name-of-package"
+# eg. "@npm//lodash"
+RUNTIME_DEPS = [
+ "@npm//@elastic/eui",
+ "@npm//@storybook/addon-actions",
+ "@npm//enzyme",
+ "@npm//react",
+ "//packages/kbn-i18n-react",
+ "//packages/kbn-i18n",
+ "//packages/shared-ux/link/redirect_app",
+]
+
+# In this array place dependencies necessary to build the types, which will include the
+# :npm_module_types target of other packages and packages from NPM, including @types/*
+# packages.
+#
+# To reference the types for another package use:
+# "//repo/relative/path/to/package:npm_module_types"
+# eg. "//packages/kbn-utils:npm_module_types"
+#
+# References to NPM packages work the same as RUNTIME_DEPS
+TYPES_DEPS = [
+ "@npm//@elastic/eui",
+ "@npm//@storybook/addon-actions",
+ "@npm//@types/enzyme",
+ "@npm//@types/jest",
+ "@npm//@types/node",
+ "@npm//@types/react",
+ "//packages/kbn-ambient-ui-types",
+ "//packages/kbn-i18n-react:npm_module_types",
+ "//packages/kbn-i18n:npm_module_types",
+ "//packages/shared-ux/link/redirect_app:npm_module_types",
+]
+
+jsts_transpiler(
+ name = "target_node",
+ srcs = SRCS,
+ build_pkg_name = package_name(),
+)
+
+jsts_transpiler(
+ name = "target_web",
+ srcs = SRCS,
+ build_pkg_name = package_name(),
+ web = True,
+ additional_args = [
+ "--copy-files",
+ "--quiet"
+ ],
+)
+
+ts_config(
+ name = "tsconfig",
+ src = "tsconfig.json",
+ deps = [
+ "//:tsconfig.base.json",
+ "//:tsconfig.bazel.json",
+ ],
+)
+
+ts_project(
+ name = "tsc_types",
+ args = ['--pretty'],
+ srcs = SRCS,
+ deps = TYPES_DEPS,
+ declaration = True,
+ emit_declaration_only = True,
+ out_dir = "target_types",
+ root_dir = "src",
+ tsconfig = ":tsconfig",
+)
+
+js_library(
+ name = PKG_DIRNAME,
+ srcs = NPM_MODULE_EXTRA_FILES,
+ deps = RUNTIME_DEPS + [":target_node", ":target_web"],
+ package_name = PKG_REQUIRE_NAME,
+ visibility = ["//visibility:public"],
+)
+
+pkg_npm(
+ name = "npm_module",
+ deps = [":" + PKG_DIRNAME],
+)
+
+filegroup(
+ name = "build",
+ srcs = [":npm_module"],
+ visibility = ["//visibility:public"],
+)
+
+pkg_npm_types(
+ name = "npm_module_types",
+ srcs = SRCS,
+ deps = [":tsc_types"],
+ package_name = PKG_REQUIRE_NAME,
+ tsconfig = ":tsconfig",
+ visibility = ["//visibility:public"],
+)
+
+filegroup(
+ name = "build_types",
+ srcs = [":npm_module_types"],
+ visibility = ["//visibility:public"],
+)
diff --git a/packages/shared-ux/card/no_data/README.mdx b/packages/shared-ux/card/no_data/README.mdx
new file mode 100644
index 0000000000000..e2b044c27ac44
--- /dev/null
+++ b/packages/shared-ux/card/no_data/README.mdx
@@ -0,0 +1,29 @@
+---
+id: sharedUX/Components/NoDataCard
+slug: /shared-ux/components/no-data-card
+title: No Data Card
+summary: A card displayed when no data is available is available in Kibana.
+tags: ['shared-ux', 'component']
+date: 2022-06-15
+---
+
+## Description
+
+A wrapper around `EuiCard` tailored for use in Kibana solutions when no data is available.
+
+## Usage
+
+All of the `EuiCard` props are available with the exception of `layout`. A default `description` and `button` are provided, but can be overridden in specific use cases.
+
+The `NoDataCard` connected component uses:
+
+- `navLinks.integrations` from `coreStart.application.capabilities` to determine if the user has access to the Integrations page.
+- `addBasePath` from `coreStart` to navigate to the Integrations page.
+
+## API
+| Export | Description |
+|---|---|
+| `NoDataCardProvider` | Provides contextual services to `NoDataCard`. |
+| `NoDataCardKibanaProvider` | Maps Kibana dependencies to provide contextual services to `NoDataCard`. |
+| `NoDataCard` | Uses a `Provider` to access contextual services to populate props on the `NoDataCardComponent`. |
+| `NoDataCardComponent` | The pure component, a pre-configured **EuiCard**. |
\ No newline at end of file
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/index.ts b/packages/shared-ux/card/no_data/jest.config.js
similarity index 67%
rename from packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/index.ts
rename to packages/shared-ux/card/no_data/jest.config.js
index e4cdeb401584f..47ce28115535f 100644
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/index.ts
+++ b/packages/shared-ux/card/no_data/jest.config.js
@@ -5,6 +5,9 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
-export { NoDataCard } from './no_data_card';
-export { ElasticAgentCard } from './elastic_agent_card';
-export type { NoDataCardProps, ElasticAgentCardProps } from './types';
+
+module.exports = {
+ preset: '@kbn/test',
+ rootDir: '../../../..',
+ roots: ['/packages/shared-ux/card/no_data'],
+};
diff --git a/packages/shared-ux/card/no_data/package.json b/packages/shared-ux/card/no_data/package.json
new file mode 100644
index 0000000000000..a1d3efd5a6985
--- /dev/null
+++ b/packages/shared-ux/card/no_data/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@kbn/shared-ux-card-no-data",
+ "private": true,
+ "version": "1.0.0",
+ "main": "./target_node/index.js",
+ "browser": "./target_web/index.js",
+ "license": "SSPL-1.0 OR Elastic License 2.0"
+}
diff --git a/packages/shared-ux/card/no_data/src/__snapshots__/no_data_card.component.test.tsx.snap b/packages/shared-ux/card/no_data/src/__snapshots__/no_data_card.component.test.tsx.snap
new file mode 100644
index 0000000000000..17eb4ef8804cd
--- /dev/null
+++ b/packages/shared-ux/card/no_data/src/__snapshots__/no_data_card.component.test.tsx.snap
@@ -0,0 +1,117 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`NoDataCardComponent props button 1`] = `
+
+ Button
+
+ }
+ image={}
+ isDisabled={false}
+ paddingSize="l"
+ title={
+
+
+ Add Elastic Agent
+
+
+ }
+/>
+`;
+
+exports[`NoDataCardComponent props href 1`] = `
+
+ Add Elastic Agent
+
+ }
+ href="some path"
+ image={}
+ isDisabled={false}
+ paddingSize="l"
+ title={
+
+
+ Add Elastic Agent
+
+
+ }
+/>
+`;
+
+exports[`NoDataCardComponent renders 1`] = `
+
+ Add Elastic Agent
+
+ }
+ image={}
+ isDisabled={false}
+ paddingSize="l"
+ title={
+
+
+ Add Elastic Agent
+
+
+ }
+/>
+`;
+
+exports[`NoDataCardComponent renders with canAccessFleet false 1`] = `
+
+ This integration is not yet enabled. Your administrator has the required permissions to turn it on.
+
+ }
+ image={}
+ isDisabled={true}
+ paddingSize="l"
+ title={
+
+ Contact your administrator
+
+ }
+/>
+`;
diff --git a/packages/shared-ux/card/no_data/src/__snapshots__/no_data_card.test.tsx.snap b/packages/shared-ux/card/no_data/src/__snapshots__/no_data_card.test.tsx.snap
new file mode 100644
index 0000000000000..1f4277ffd139f
--- /dev/null
+++ b/packages/shared-ux/card/no_data/src/__snapshots__/no_data_card.test.tsx.snap
@@ -0,0 +1,356 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`NoDataCard props button 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`NoDataCard props extends EuiCardProps 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`NoDataCard props href 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`NoDataCard props no access to Fleet 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This integration is not yet enabled. Your administrator has the required permissions to turn it on.
+
+
+
+
+
+
+`;
+
+exports[`NoDataCard renders 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/assets/elastic_agent_card.svg b/packages/shared-ux/card/no_data/src/assets/elastic_agent_card.svg
similarity index 100%
rename from packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/assets/elastic_agent_card.svg
rename to packages/shared-ux/card/no_data/src/assets/elastic_agent_card.svg
diff --git a/packages/shared-ux/card/no_data/src/index.ts b/packages/shared-ux/card/no_data/src/index.ts
new file mode 100644
index 0000000000000..24463007b5a8c
--- /dev/null
+++ b/packages/shared-ux/card/no_data/src/index.ts
@@ -0,0 +1,19 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+export { NoDataCard } from './no_data_card';
+export type { Props as NoDataCardProps } from './no_data_card';
+
+export { NoDataCardKibanaProvider, NoDataCardProvider } from './services';
+export type { NoDataCardKibanaDependencies, NoDataCardServices } from './services';
+
+export {
+ getMockServices as getNoDataCardMockServices,
+ getStoryArgTypes as getNoDataCardStoryArgTypes,
+ getStoryServices as getNoDataCardStoryServices,
+} from './mocks';
diff --git a/packages/shared-ux/card/no_data/src/mocks.ts b/packages/shared-ux/card/no_data/src/mocks.ts
new file mode 100644
index 0000000000000..d5ec849e1456b
--- /dev/null
+++ b/packages/shared-ux/card/no_data/src/mocks.ts
@@ -0,0 +1,88 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { action } from '@storybook/addon-actions';
+import {
+ getRedirectAppLinksMockServices,
+ getRedirectAppLinksStoryArgTypes,
+ getRedirectAppLinksStoryServices,
+} from '@kbn/shared-ux-link-redirect-app';
+
+import { NoDataCardServices } from './services';
+
+/**
+ * Parameters drawn from the Storybook arguments collection that customize a component story.
+ */
+export type Params = Record, any>;
+
+/**
+ * Returns Storybook-compatible service abstractions for the `NoDataCard` Provider.
+ */
+export const getStoryServices = (params: Params) => {
+ const services: NoDataCardServices = {
+ ...getRedirectAppLinksStoryServices(),
+ ...params,
+ addBasePath: (path) => {
+ action('addBasePath')(path);
+ return path;
+ },
+ };
+
+ return services;
+};
+
+/**
+ * Returns the Storybook arguments for `NoDataCard`, for its stories and for
+ * consuming component stories.
+ */
+export const getStoryArgTypes = () => ({
+ ...getRedirectAppLinksStoryArgTypes(),
+ canAccessFleet: {
+ control: 'boolean',
+ defaultValue: true,
+ },
+ category: {
+ control: {
+ type: 'text',
+ },
+ defaultValue: '',
+ },
+ title: {
+ control: {
+ type: 'text',
+ },
+ defaultValue: '',
+ },
+ description: {
+ control: {
+ type: 'text',
+ },
+ defaultValue: '',
+ },
+ button: {
+ control: {
+ type: 'text',
+ },
+ defaultValue: '',
+ },
+});
+
+/**
+ * Returns the Jest-compatible service abstractions for the `NoDataCard` Provider.
+ */
+export const getMockServices = (params?: Params) => {
+ const { canAccessFleet } = params || { canAccessFleet: true };
+
+ const services: NoDataCardServices = {
+ ...getRedirectAppLinksMockServices(),
+ canAccessFleet,
+ addBasePath: (path) => path,
+ };
+
+ return services;
+};
diff --git a/packages/shared-ux/card/no_data/src/no_data_card.component.test.tsx b/packages/shared-ux/card/no_data/src/no_data_card.component.test.tsx
new file mode 100644
index 0000000000000..72d179602e6d5
--- /dev/null
+++ b/packages/shared-ux/card/no_data/src/no_data_card.component.test.tsx
@@ -0,0 +1,36 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import React from 'react';
+import { shallow } from 'enzyme';
+
+import { NoDataCard } from './no_data_card.component';
+
+describe('NoDataCardComponent', () => {
+ test('renders', () => {
+ const component = shallow();
+ expect(component).toMatchSnapshot();
+ });
+
+ test('renders with canAccessFleet false', () => {
+ const component = shallow();
+ expect(component).toMatchSnapshot();
+ });
+
+ describe('props', () => {
+ test('button', () => {
+ const component = shallow();
+ expect(component).toMatchSnapshot();
+ });
+
+ test('href', () => {
+ const component = shallow();
+ expect(component).toMatchSnapshot();
+ });
+ });
+});
diff --git a/packages/shared-ux/card/no_data/src/no_data_card.component.tsx b/packages/shared-ux/card/no_data/src/no_data_card.component.tsx
new file mode 100644
index 0000000000000..43c4e9cd3a4af
--- /dev/null
+++ b/packages/shared-ux/card/no_data/src/no_data_card.component.tsx
@@ -0,0 +1,136 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import React, { MouseEventHandler, ReactNode } from 'react';
+import {
+ EuiButton,
+ EuiCard,
+ EuiScreenReaderOnly,
+ EuiTextColor,
+ EuiCardProps,
+ EuiImage,
+} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+
+import { NoDataCardStyles } from './no_data_card.styles';
+import ElasticAgentCardIllustration from './assets/elastic_agent_card.svg';
+
+export type Props = Partial<
+ Omit
+> & {
+ /**
+ * Provide just a string for the button's label, or a whole component;
+ * The button will be hidden completely if `isDisabled=true`
+ */
+ button?: string | ReactNode;
+ /** Remapping `onClick` to any element */
+ onClick?: MouseEventHandler;
+ /**
+ * Description for the card;
+ * If not provided, the default will be used
+ */
+ description?: string | ReactNode;
+ /** Category to auto-select within Fleet */
+ category?: string;
+ /** True if the person has permission to access Fleet, false otherwise */
+ canAccessFleet?: boolean;
+};
+
+const noPermissionTitle = i18n.translate('sharedUXPackages.card.noData.noPermission.title', {
+ defaultMessage: `Contact your administrator`,
+});
+
+const noPermissionDescription = i18n.translate(
+ 'sharedUXPackages.card.noData.noPermission.description',
+ {
+ defaultMessage: `This integration is not yet enabled. Your administrator has the required permissions to turn it on.`,
+ }
+);
+
+const defaultTitle = i18n.translate('sharedUXPackages.card.noData.title', {
+ defaultMessage: 'Add Elastic Agent',
+});
+
+const defaultDescription = i18n.translate('sharedUXPackages.card.noData.description', {
+ defaultMessage: `Use Elastic Agent for a simple, unified way to collect data from your machines.`,
+});
+
+const Image = () => (
+
+);
+
+/**
+ * Creates a specific NoDataCard pointing users to Integrations when `canAccessFleet`
+ */
+export const NoDataCard = ({
+ title: titleProp,
+ description: descriptionProp,
+ canAccessFleet,
+ button,
+ ...props
+}: Props) => {
+ const styles = NoDataCardStyles();
+
+ const footer = () => {
+ // Don't render the footer action if disabled
+ if (!canAccessFleet) {
+ return;
+ }
+
+ // Render a custom footer action if the button is not a simple string
+ if (button && typeof button !== 'string') {
+ return button;
+ }
+
+ // Default footer action is a button with the provided or default string
+ return {button || titleProp || defaultTitle};
+ };
+
+ const title = () => {
+ if (!canAccessFleet) {
+ return {noPermissionTitle};
+ }
+
+ return (
+
+ {titleProp || defaultTitle}
+
+ );
+ };
+
+ const description = () => {
+ if (!canAccessFleet) {
+ return {noPermissionDescription};
+ }
+
+ return descriptionProp || defaultDescription;
+ };
+
+ return (
+ }
+ {...props}
+ />
+ );
+};
diff --git a/packages/shared-ux/card/no_data/src/no_data_card.stories.tsx b/packages/shared-ux/card/no_data/src/no_data_card.stories.tsx
new file mode 100644
index 0000000000000..38f299d3d3d35
--- /dev/null
+++ b/packages/shared-ux/card/no_data/src/no_data_card.stories.tsx
@@ -0,0 +1,45 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import React from 'react';
+
+import { Params, getStoryArgTypes, getStoryServices } from './mocks';
+
+import { NoDataCard as Component } from './no_data_card.component';
+import { NoDataCard as ConnectedComponent } from './no_data_card';
+import { NoDataCardProvider } from './services';
+
+import mdx from '../README.mdx';
+
+export default {
+ title: 'No Data/Card',
+ description: 'A solution-specific wrapper around `EuiCard`, to be used on `NoData` page',
+ parameters: {
+ docs: {
+ page: mdx,
+ },
+ },
+};
+
+const argTypes = getStoryArgTypes();
+
+export const NoDataCard = (params: Params) => {
+ return (
+
+
+
+ );
+};
+
+NoDataCard.argTypes = argTypes;
+
+export const NoDataCardComponent = (params: Params) => {
+ return ;
+};
+
+NoDataCardComponent.argTypes = argTypes;
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.styles.ts b/packages/shared-ux/card/no_data/src/no_data_card.styles.ts
similarity index 100%
rename from packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.styles.ts
rename to packages/shared-ux/card/no_data/src/no_data_card.styles.ts
diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.test.tsx b/packages/shared-ux/card/no_data/src/no_data_card.test.tsx
similarity index 73%
rename from packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.test.tsx
rename to packages/shared-ux/card/no_data/src/no_data_card.test.tsx
index 6bbed463f23ed..0f659ad7a7f50 100644
--- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.test.tsx
+++ b/packages/shared-ux/card/no_data/src/no_data_card.test.tsx
@@ -6,11 +6,23 @@
* Side Public License, v 1.
*/
-import { render } from 'enzyme';
+import { render as enzymeRender } from 'enzyme';
import React from 'react';
+
import { NoDataCard } from './no_data_card';
+import { NoDataCardProvider } from './services';
+
+const services = {
+ addBasePath: (path: string) => path,
+ navigateToUrl: () => {},
+};
describe('NoDataCard', () => {
+ const render = (element: React.ReactElement, canAccessFleet: boolean = true) =>
+ enzymeRender(
+ {element}
+ );
+
test('renders', () => {
const component = render();
expect(component).toMatchSnapshot();
@@ -31,14 +43,10 @@ describe('NoDataCard', () => {
expect(component).toMatchSnapshot();
});
- test('isDisabled', () => {
+ test('no access to Fleet', () => {
const component = render(
-
+ ,
+ false
);
expect(component).toMatchSnapshot();
});
diff --git a/packages/shared-ux/card/no_data/src/no_data_card.tsx b/packages/shared-ux/card/no_data/src/no_data_card.tsx
new file mode 100644
index 0000000000000..a58ee5bc9d08b
--- /dev/null
+++ b/packages/shared-ux/card/no_data/src/no_data_card.tsx
@@ -0,0 +1,41 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import React, { useMemo } from 'react';
+import { RedirectAppLinksContainer } from '@kbn/shared-ux-link-redirect-app';
+
+import { NoDataCard as Component, Props as ComponentProps } from './no_data_card.component';
+
+import { useServices } from './services';
+
+export type Props = Omit;
+
+export const NoDataCard = ({ href: srcHref, category, description, ...props }: Props) => {
+ const { canAccessFleet, addBasePath } = useServices();
+
+ const href = useMemo(() => {
+ if (srcHref) {
+ return srcHref;
+ }
+
+ // TODO: get this URL from a locator
+ const prefix = '/app/integrations/browse';
+
+ if (category) {
+ return addBasePath(`${prefix}/${category}`);
+ }
+
+ return addBasePath(prefix);
+ }, [addBasePath, srcHref, category]);
+
+ return (
+
+
+
+ );
+};
diff --git a/packages/shared-ux/card/no_data/src/services.tsx b/packages/shared-ux/card/no_data/src/services.tsx
new file mode 100644
index 0000000000000..c4937a6d21da9
--- /dev/null
+++ b/packages/shared-ux/card/no_data/src/services.tsx
@@ -0,0 +1,97 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import React, { FC, useContext } from 'react';
+import {
+ RedirectAppLinksServices,
+ RedirectAppLinksKibanaDependencies,
+ RedirectAppLinksProvider,
+ RedirectAppLinksKibanaProvider,
+} from '@kbn/shared-ux-link-redirect-app';
+
+/**
+ * A list of services that are consumed by this component.
+ */
+interface Services {
+ addBasePath: (path: string) => string;
+ canAccessFleet: boolean;
+}
+
+const Context = React.createContext(null);
+
+/**
+ * Services that are consumed by this component and its dependencies.
+ */
+export type NoDataCardServices = Services & RedirectAppLinksServices;
+
+/**
+ * A Context Provider that provides services to the component and its dependencies.
+ */
+export const NoDataCardProvider: FC = ({ children, ...services }) => {
+ const { addBasePath, canAccessFleet } = services;
+
+ return (
+
+ {children}
+
+ );
+};
+
+interface KibanaDependencies {
+ coreStart: {
+ http: {
+ basePath: {
+ prepend: (path: string) => string;
+ };
+ };
+ application: {
+ capabilities: {
+ navLinks: Record;
+ };
+ };
+ };
+}
+/**
+ * An interface containing a collection of Kibana plugins and services required to
+ * render this component as well as its dependencies.
+ */
+export type NoDataCardKibanaDependencies = KibanaDependencies & RedirectAppLinksKibanaDependencies;
+
+/**
+ * Kibana-specific Provider that maps dependencies to services.
+ */
+export const NoDataCardKibanaProvider: FC = ({
+ children,
+ ...dependencies
+}) => {
+ const value: Services = {
+ addBasePath: dependencies.coreStart.http.basePath.prepend,
+ canAccessFleet: dependencies.coreStart.application.capabilities.navLinks.integrations,
+ };
+
+ return (
+
+ {children}
+
+ );
+};
+
+/**
+ * React hook for accessing pre-wired services.
+ */
+export function useServices() {
+ const context = useContext(Context);
+
+ if (!context) {
+ throw new Error(
+ 'NoDataCard Context is missing. Ensure your component or React root is wrapped with NoDataCardContext.'
+ );
+ }
+
+ return context;
+}
diff --git a/packages/shared-ux/card/no_data/tsconfig.json b/packages/shared-ux/card/no_data/tsconfig.json
new file mode 100644
index 0000000000000..44b240540718d
--- /dev/null
+++ b/packages/shared-ux/card/no_data/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "extends": "../../../../tsconfig.bazel.json",
+ "compilerOptions": {
+ "declaration": true,
+ "emitDeclarationOnly": true,
+ "outDir": "target_types",
+ "rootDir": "src",
+ "stripInternal": false,
+ "types": [
+ "jest",
+ "node",
+ "react",
+ "@emotion/react/types/css-prop",
+ "@kbn/ambient-ui-types"
+ ]
+ },
+ "include": [
+ "src/**/*"
+ ]
+}
diff --git a/packages/shared-ux/link/redirect_app/src/index.tsx b/packages/shared-ux/link/redirect_app/src/index.tsx
index 09317ebab59f7..0d1c61242edb3 100644
--- a/packages/shared-ux/link/redirect_app/src/index.tsx
+++ b/packages/shared-ux/link/redirect_app/src/index.tsx
@@ -10,16 +10,27 @@ export { RedirectAppLinks as RedirectAppLinksContainer } from './redirect_app_li
export { RedirectAppLinks as RedirectAppLinksComponent } from './redirect_app_links.component';
export { RedirectAppLinksKibanaProvider, RedirectAppLinksProvider } from './services';
+export type {
+ Services as RedirectAppLinksServices,
+ KibanaDependencies as RedirectAppLinksKibanaDependencies,
+} from './services';
+
+export {
+ getMockServices as getRedirectAppLinksMockServices,
+ getStoryArgTypes as getRedirectAppLinksStoryArgTypes,
+ getStoryServices as getRedirectAppLinksStoryServices,
+} from './mocks';
+
import React, { FC } from 'react';
import { RedirectAppLinks as RedirectAppLinksContainer } from './redirect_app_links';
import {
Services,
- KibanaServices,
+ KibanaDependencies,
RedirectAppLinksKibanaProvider,
RedirectAppLinksProvider,
} from './services';
-const isKibanaContract = (services: any): services is KibanaServices => {
+const isKibanaContract = (services: any): services is KibanaDependencies => {
return typeof services.coreStart !== 'undefined';
};
@@ -28,12 +39,22 @@ const isKibanaContract = (services: any): services is KibanaServices => {
* `RedirectAppLinksKibanaProvider` based on the services provided, creating a single component
* with which consumers can wrap their components or solutions.
*/
-export const RedirectAppLinks: FC = ({ children, ...services }) => {
+export const RedirectAppLinks: FC = ({ children, ...services }) => {
const container = {children};
- return isKibanaContract(services) ? (
- {container}
- ) : (
- {container}
+ if (isKibanaContract(services)) {
+ const { coreStart } = services;
+ return (
+
+ {container}
+
+ );
+ }
+
+ const { navigateToUrl, currentAppId } = services;
+ return (
+
+ {container}
+
);
};
diff --git a/packages/shared-ux/link/redirect_app/src/mocks.ts b/packages/shared-ux/link/redirect_app/src/mocks.ts
new file mode 100644
index 0000000000000..4b5519dd646bb
--- /dev/null
+++ b/packages/shared-ux/link/redirect_app/src/mocks.ts
@@ -0,0 +1,46 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { action } from '@storybook/addon-actions';
+
+import { Services } from './services';
+
+/**
+ * Parameters drawn from the Storybook arguments collection that customize a component story.
+ */
+export type Params = Record, any>;
+
+/**
+ * Returns Storybook-compatible service abstractions for the `NoDataCard` Provider.
+ */
+export const getStoryServices = () => {
+ const services: Services = {
+ navigateToUrl: action('navigateToUrl'),
+ currentAppId: 'currentAppId',
+ };
+
+ return services;
+};
+
+/**
+ * Returns the Storybook arguments for `NoDataCard`, for its stories and for
+ * consuming component stories.
+ */
+export const getStoryArgTypes = () => ({});
+
+/**
+ * Returns the Jest-compatible service abstractions for the `NoDataCard` Provider.
+ */
+export const getMockServices = () => {
+ const services: Services = {
+ navigateToUrl: jest.fn(),
+ currentAppId: 'currentAppId',
+ };
+
+ return services;
+};
diff --git a/packages/shared-ux/link/redirect_app/src/redirect_app_links.component.tsx b/packages/shared-ux/link/redirect_app/src/redirect_app_links.component.tsx
index 477471fe71824..f0da5b307fbd1 100644
--- a/packages/shared-ux/link/redirect_app/src/redirect_app_links.component.tsx
+++ b/packages/shared-ux/link/redirect_app/src/redirect_app_links.component.tsx
@@ -29,12 +29,7 @@ export interface Props extends DetailedHTMLProps,
*
* ```
*/
-export const RedirectAppLinks: FC = ({
- children,
- navigateToUrl,
- currentAppId,
- ...otherProps
-}) => {
+export const RedirectAppLinks: FC = ({ children, navigateToUrl, currentAppId }) => {
const containerRef = useRef(null);
const handleClick: MouseEventHandler = useCallback(
@@ -50,7 +45,7 @@ export const RedirectAppLinks: FC = ({
return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events
-
+
{children}
);
diff --git a/packages/shared-ux/link/redirect_app/src/redirect_app_links.stories.tsx b/packages/shared-ux/link/redirect_app/src/redirect_app_links.stories.tsx
index 9bb3d0d9782d4..1b77f7148964e 100644
--- a/packages/shared-ux/link/redirect_app/src/redirect_app_links.stories.tsx
+++ b/packages/shared-ux/link/redirect_app/src/redirect_app_links.stories.tsx
@@ -10,11 +10,12 @@ import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import React from 'react';
import { action } from '@storybook/addon-actions';
-import { RedirectAppLinks } from '.';
+import { RedirectAppLinks as Component } from '.';
+import { getStoryArgTypes, getStoryServices } from './mocks';
import mdx from '../README.mdx';
export default {
- title: 'Redirect App Links',
+ title: 'Link',
description:
'An "area of effect" component which intercepts clicks on anchor elements and redirects them to Kibana solutions without a page refresh.',
parameters: {
@@ -24,16 +25,10 @@ export default {
},
};
-export const Component = () => {
- const navigateToUrl = async (url: string) => {
- action('navigateToUrl')(url);
- };
-
- const currentAppId = 'abc123';
-
+export const RedirectAppLinks = () => {
return (
<>
-
+
{
-
+
{
>
);
};
+
+RedirectAppLinks.argTypes = getStoryArgTypes();
diff --git a/packages/shared-ux/link/redirect_app/src/redirect_app_links.tsx b/packages/shared-ux/link/redirect_app/src/redirect_app_links.tsx
index 1e805ad4475b6..9a069881b2128 100644
--- a/packages/shared-ux/link/redirect_app/src/redirect_app_links.tsx
+++ b/packages/shared-ux/link/redirect_app/src/redirect_app_links.tsx
@@ -6,15 +6,10 @@
* Side Public License, v 1.
*/
-import React from 'react';
+import React, { FC } from 'react';
import { useServices } from './services';
-import {
- RedirectAppLinks as Component,
- Props as ComponentProps,
-} from './redirect_app_links.component';
-
-type Props = Omit;
+import { RedirectAppLinks as Component } from './redirect_app_links.component';
/**
* A service-enabled component that provides Kibana-specific functionality to the `RedirectAppLinks`
@@ -27,4 +22,6 @@ type Props = Omit;
*
* ```
*/
-export const RedirectAppLinks = (props: Props) => ;
+export const RedirectAppLinks: FC<{}> = ({ children }) => (
+ {children}
+);
diff --git a/packages/shared-ux/link/redirect_app/src/services.tsx b/packages/shared-ux/link/redirect_app/src/services.tsx
index 22bc5a5cd0c55..b29d82f8eea13 100644
--- a/packages/shared-ux/link/redirect_app/src/services.tsx
+++ b/packages/shared-ux/link/redirect_app/src/services.tsx
@@ -25,8 +25,9 @@ const RedirectAppLinksContext = React.createContext(null);
* Contextual services Provider.
*/
export const RedirectAppLinksProvider: FC = ({ children, ...services }) => {
+ const { navigateToUrl, currentAppId } = services;
return (
-
+
{children}
);
@@ -35,7 +36,7 @@ export const RedirectAppLinksProvider: FC = ({ children, ...services }
/**
* Kibana-specific contextual services to be adapted for this component.
*/
-export interface KibanaServices {
+export interface KibanaDependencies {
coreStart: {
application: {
currentAppId$: Observable;
@@ -47,7 +48,7 @@ export interface KibanaServices {
/**
* Kibana-specific contextual services Provider.
*/
-export const RedirectAppLinksKibanaProvider: FC = ({ children, coreStart }) => {
+export const RedirectAppLinksKibanaProvider: FC = ({ children, coreStart }) => {
const { navigateToUrl, currentAppId$ } = coreStart.application;
const currentAppId = useObservable(currentAppId$, undefined);
diff --git a/packages/shared-ux/page/analytics_no_data/src/analytics_no_data_page.stories.tsx b/packages/shared-ux/page/analytics_no_data/src/analytics_no_data_page.stories.tsx
index d5d82d801fc8d..8cb9b3aaa5f7e 100644
--- a/packages/shared-ux/page/analytics_no_data/src/analytics_no_data_page.stories.tsx
+++ b/packages/shared-ux/page/analytics_no_data/src/analytics_no_data_page.stories.tsx
@@ -16,7 +16,7 @@ import mdx from '../README.mdx';
import { Params, getStoryArgTypes, getStoryServices } from './mocks';
export default {
- title: 'No Data/Analytics',
+ title: 'No Data/Analytics Page',
description: 'An Analytics-specific version of KibanaNoDataPage.',
parameters: {
docs: {
diff --git a/packages/shared-ux/page/kibana_no_data/src/kibana_no_data_page.stories.tsx b/packages/shared-ux/page/kibana_no_data/src/kibana_no_data_page.stories.tsx
index 206b958e64771..c18adc20e4af0 100644
--- a/packages/shared-ux/page/kibana_no_data/src/kibana_no_data_page.stories.tsx
+++ b/packages/shared-ux/page/kibana_no_data/src/kibana_no_data_page.stories.tsx
@@ -16,7 +16,7 @@ import { KibanaNoDataPageProvider } from './services';
import mdx from '../README.mdx';
export default {
- title: 'No Data/Kibana',
+ title: 'No Data/Kibana Page',
description: 'A component to display when there is no data available',
parameters: {
docs: {
diff --git a/packages/shared-ux/page/kibana_no_data/src/mocks.ts b/packages/shared-ux/page/kibana_no_data/src/mocks.ts
index e88097c933849..d91949ddc6c32 100644
--- a/packages/shared-ux/page/kibana_no_data/src/mocks.ts
+++ b/packages/shared-ux/page/kibana_no_data/src/mocks.ts
@@ -14,6 +14,12 @@ import {
getNoDataViewsPromptMockServices,
} from '@kbn/shared-ux-prompt-no-data-views';
+import {
+ getNoDataCardMockServices,
+ getNoDataCardStoryArgTypes,
+ getNoDataCardStoryServices,
+} from '@kbn/shared-ux-card-no-data';
+
import { KibanaNoDataPageServices } from './services';
// TODO: clintandrewhall - this looks (and is) a bit complicated because the No Data View
@@ -32,6 +38,8 @@ export const getStoryServices = (params: StoryParams) => {
const { canCreateNewDataView, dataViewsDocLink, openDataViewEditor } =
getNoDataViewsPromptStorybookServices(params);
+ const { addBasePath, canAccessFleet } = getNoDataCardStoryServices(params);
+
// Workaround to leverage the services package.
const { application, data, docLinks, editors, http, permissions, platform } =
servicesFactory(params);
@@ -47,6 +55,8 @@ export const getStoryServices = (params: StoryParams) => {
canCreateNewDataView,
dataViewsDocLink,
openDataViewEditor,
+ addBasePath,
+ canAccessFleet,
};
return services;
@@ -75,6 +85,7 @@ export const getStoryArgTypes = () => ({
defaultValue: false,
},
...getNoDataViewsPromptStoryArgTypes(),
+ ...getNoDataCardStoryArgTypes(),
});
/**
@@ -84,6 +95,8 @@ export const getMockServices = (params?: MockServicesFactoryParams) => {
const { canCreateNewDataView, dataViewsDocLink, openDataViewEditor } =
getNoDataViewsPromptMockServices();
+ const { addBasePath, canAccessFleet } = getNoDataCardMockServices();
+
const { application, data, docLinks, editors, http, permissions, platform } =
mockServicesFactory(params);
@@ -98,6 +111,8 @@ export const getMockServices = (params?: MockServicesFactoryParams) => {
canCreateNewDataView,
dataViewsDocLink,
openDataViewEditor,
+ addBasePath,
+ canAccessFleet,
};
return services;
diff --git a/packages/shared-ux/page/kibana_no_data/src/services.tsx b/packages/shared-ux/page/kibana_no_data/src/services.tsx
index 07b5787ae8b72..47f6b9c3690f9 100644
--- a/packages/shared-ux/page/kibana_no_data/src/services.tsx
+++ b/packages/shared-ux/page/kibana_no_data/src/services.tsx
@@ -13,6 +13,8 @@ import {
NoDataViewsPromptKibanaProvider,
} from '@kbn/shared-ux-prompt-no-data-views';
+import { NoDataCardProvider, NoDataCardKibanaProvider } from '@kbn/shared-ux-card-no-data';
+
import { LegacyServicesProvider, getLegacyServices } from './legacy_services';
/**
@@ -85,7 +87,9 @@ export const KibanaNoDataPageProvider: FC = ({
}) => (
- {children}
+
+ {children}
+
);
@@ -159,7 +163,9 @@ export const KibanaNoDataPageKibanaProvider: FC
- {children}
+
+ {children}
+
);
diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json
index 3c492c1443bf7..5877421bf5d1b 100644
--- a/x-pack/plugins/translations/translations/fr-FR.json
+++ b/x-pack/plugins/translations/translations/fr-FR.json
@@ -5338,11 +5338,10 @@
"share.urlService.redirect.RedirectManager.missingParamLocator": "ID du localisateur non spécifié. Spécifiez le paramètre de recherche \"l\" dans l'URL ; ce devrait être un ID de localisateur existant.",
"share.urlService.redirect.RedirectManager.missingParamParams": "Paramètres du localisateur non spécifiés. Spécifiez le paramètre de recherche \"p\" dans l'URL ; ce devrait être un objet sérialisé JSON des paramètres du localisateur.",
"share.urlService.redirect.RedirectManager.missingParamVersion": "Version des paramètres du localisateur non spécifiée. Spécifiez le paramètre de recherche \"v\" dans l'URL ; ce devrait être la version de Kibana au moment de la génération des paramètres du localisateur.",
- "sharedUXComponents.noDataPage.elasticAgentCard.description": "Utilisez Elastic Agent pour collecter de manière simple et unifiée les données de vos machines.",
- "sharedUXComponents.noDataPage.elasticAgentCard.noPermission.description": "Cette intégration n'est pas encore activée. Votre administrateur possède les autorisations requises pour l’activer.",
- "sharedUXComponents.noDataPage.elasticAgentCard.noPermission.title": "Contactez votre administrateur",
- "sharedUXComponents.noDataPage.elasticAgentCard.title": "Ajouter Elastic Agent",
- "sharedUXComponents.pageTemplate.noDataCard.description": "Continuer sans collecter de données",
+ "sharedUXPackages.card.noData.description": "Utilisez Elastic Agent pour collecter de manière simple et unifiée les données de vos machines.",
+ "sharedUXPackages.card.noData.noPermission.description": "Cette intégration n'est pas encore activée. Votre administrateur possède les autorisations requises pour l’activer.",
+ "sharedUXPackages.card.noData.noPermission.title": "Contactez votre administrateur",
+ "sharedUXPackages.card.noData.title": "Ajouter Elastic Agent",
"sharedUXPackages.buttonToolbar.buttons.addFromLibrary.libraryButtonLabel": "Ajouter depuis la bibliothèque",
"sharedUXPackages.noDataViewsPrompt.learnMore": "Envie d'en savoir plus ?",
"sharedUXPackages.noDataViewsPrompt.readDocumentation": "Lisez les documents",
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index fa1ce7b24c45c..0c37c60acaf0d 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -5440,11 +5440,10 @@
"share.urlService.redirect.RedirectManager.missingParamLocator": "ロケーターIDが指定されていません。URLで「l」検索パラメーターを指定します。これは既存のロケーターIDにしてください。",
"share.urlService.redirect.RedirectManager.missingParamParams": "ロケーターパラメーターが指定されていません。URLで「p」検索パラメーターを指定します。これはロケーターパラメーターのJSONシリアル化オブジェクトにしてください。",
"share.urlService.redirect.RedirectManager.missingParamVersion": "ロケーターパラメーターバージョンが指定されていません。URLで「v」検索パラメーターを指定します。これはロケーターパラメーターが生成されたときのKibanaのリリースバージョンです。",
- "sharedUXComponents.noDataPage.elasticAgentCard.description": "Elasticエージェントを使用すると、シンプルで統一された方法でコンピューターからデータを収集するできます。",
- "sharedUXComponents.noDataPage.elasticAgentCard.noPermission.description": "この統合はまだ有効ではありません。管理者にはオンにするために必要なアクセス権があります。",
- "sharedUXComponents.noDataPage.elasticAgentCard.noPermission.title": "管理者にお問い合わせください",
- "sharedUXComponents.noDataPage.elasticAgentCard.title": "Elasticエージェントの追加",
- "sharedUXComponents.pageTemplate.noDataCard.description": "データを収集せずに続行",
+ "sharedUXPackages.card.noData.description": "Elasticエージェントを使用すると、シンプルで統一された方法でコンピューターからデータを収集するできます。",
+ "sharedUXPackages.card.noData.noPermission.description": "この統合はまだ有効ではありません。管理者にはオンにするために必要なアクセス権があります。",
+ "sharedUXPackages.card.noData.noPermission.title": "管理者にお問い合わせください",
+ "sharedUXPackages.card.noData.title": "Elasticエージェントの追加",
"sharedUXPackages.buttonToolbar.buttons.addFromLibrary.libraryButtonLabel": "ライブラリから追加",
"sharedUXPackages.noDataViewsPrompt.learnMore": "詳細について",
"sharedUXPackages.noDataViewsPrompt.readDocumentation": "ドキュメントを読む",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 9bcc45a9ca1ab..6b6a0df9cd5e3 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -5451,11 +5451,10 @@
"share.urlService.redirect.RedirectManager.missingParamLocator": "未指定定位器 ID。在 URL 中指定“l”搜索参数,其应为现有定位器 ID。",
"share.urlService.redirect.RedirectManager.missingParamParams": "定位器参数未指定。在 URL 中指定“p”搜索参数,其应为定位器参数的 JSON 序列化对象。",
"share.urlService.redirect.RedirectManager.missingParamVersion": "定位器参数版本未指定。在 URL 中指定“v”搜索参数,其应为生成定位器参数时 Kibana 的版本。",
- "sharedUXComponents.noDataPage.elasticAgentCard.description": "使用 Elastic 代理以简单统一的方式从您的计算机中收集数据。",
- "sharedUXComponents.noDataPage.elasticAgentCard.noPermission.description": "尚未启用此集成。您的管理员具有打开它所需的权限。",
- "sharedUXComponents.noDataPage.elasticAgentCard.noPermission.title": "请联系您的管理员",
- "sharedUXComponents.noDataPage.elasticAgentCard.title": "添加 Elastic 代理",
- "sharedUXComponents.pageTemplate.noDataCard.description": "继续,而不收集数据",
+ "sharedUXPackages.card.noData.description": "使用 Elastic 代理以简单统一的方式从您的计算机中收集数据。",
+ "sharedUXPackages.card.noData.noPermission.description": "尚未启用此集成。您的管理员具有打开它所需的权限。",
+ "sharedUXPackages.card.noData.noPermission.title": "请联系您的管理员",
+ "sharedUXPackages.card.noData.title": "添加 Elastic 代理",
"sharedUXPackages.buttonToolbar.buttons.addFromLibrary.libraryButtonLabel": "从库中添加",
"sharedUXPackages.noDataViewsPrompt.learnMore": "希望了解详情?",
"sharedUXPackages.noDataViewsPrompt.readDocumentation": "阅读文档",
diff --git a/yarn.lock b/yarn.lock
index 649e628ecf74a..2d8dde05811f5 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3351,6 +3351,10 @@
version "0.0.0"
uid ""
+"@kbn/shared-ux-card-no-data@link:bazel-bin/packages/shared-ux/card/no_data":
+ version "0.0.0"
+ uid ""
+
"@kbn/shared-ux-components@link:bazel-bin/packages/kbn-shared-ux-components":
version "0.0.0"
uid ""
@@ -6722,6 +6726,10 @@
version "0.0.0"
uid ""
+"@types/kbn__shared-ux-card-no-data@link:bazel-bin/packages/shared-ux/card/no_data/npm_module_types":
+ version "0.0.0"
+ uid ""
+
"@types/kbn__shared-ux-components@link:bazel-bin/packages/kbn-shared-ux-components/npm_module_types":
version "0.0.0"
uid ""