diff --git a/package.json b/package.json index dabdec586151a..3f4a4b5e36867 100644 --- a/package.json +++ b/package.json @@ -182,6 +182,7 @@ "@kbn/shared-ux-button-exit-full-screen": "link:bazel-bin/packages/shared-ux/button/exit_full_screen", "@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", "@kbn/shared-ux-services": "link:bazel-bin/packages/kbn-shared-ux-services", "@kbn/shared-ux-storybook": "link:bazel-bin/packages/kbn-shared-ux-storybook", "@kbn/shared-ux-utility": "link:bazel-bin/packages/kbn-shared-ux-utility", @@ -671,6 +672,7 @@ "@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-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", "@types/kbn__shared-ux-services": "link:bazel-bin/packages/kbn-shared-ux-services/npm_module_types", "@types/kbn__shared-ux-storybook": "link:bazel-bin/packages/kbn-shared-ux-storybook/npm_module_types", "@types/kbn__shared-ux-utility": "link:bazel-bin/packages/kbn-shared-ux-utility/npm_module_types", diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index 6ec358fb360c9..5f435f583a36a 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -112,6 +112,7 @@ filegroup( "//packages/shared-ux/avatar/solution:build", "//packages/shared-ux/button/exit_full_screen:build", "//packages/shared-ux/link/redirect_app:build", + "//packages/shared-ux/page/analytics_no_data:build", ], ) @@ -207,6 +208,7 @@ filegroup( "//packages/shared-ux/avatar/solution:build_types", "//packages/shared-ux/button/exit_full_screen:build_types", "//packages/shared-ux/link/redirect_app:build_types", + "//packages/shared-ux/page/analytics_no_data:build_types", ], ) diff --git a/packages/shared-ux/page/analytics_no_data/BUILD.bazel b/packages/shared-ux/page/analytics_no_data/BUILD.bazel new file mode 100644 index 0000000000000..ad687fe8a220b --- /dev/null +++ b/packages/shared-ux/page/analytics_no_data/BUILD.bazel @@ -0,0 +1,139 @@ +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 = "analytics_no_data" +PKG_REQUIRE_NAME = "@kbn/shared-ux-page-analytics-no-data" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + "src/**/*.tsx", + "src/**/*.mdx", + ], + 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//react", + "@npm//rxjs", + "//packages/kbn-i18n", + "//packages/kbn-shared-ux-services", + "//packages/kbn-shared-ux-components", + "//packages/kbn-shared-ux-storybook" +] + +# 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//@types/node", + "@npm//@types/jest", + "@npm//@types/react", + "//packages/kbn-i18n:npm_module_types", + "//packages/kbn-shared-ux-services:npm_module_types", + "//packages/kbn-shared-ux-storybook:npm_module_types", + "//packages/kbn-shared-ux-components:npm_module_types", + "//packages/kbn-ambient-ui-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/page/analytics_no_data/README.mdx b/packages/shared-ux/page/analytics_no_data/README.mdx new file mode 100644 index 0000000000000..ab8cf8d1cb063 --- /dev/null +++ b/packages/shared-ux/page/analytics_no_data/README.mdx @@ -0,0 +1,16 @@ +--- +id: sharedUX/Components/AnalyticsNoDataPage +slug: /shared-ux/components/analytics-no-data-page +title: Analytics "No Data" Page +summary: An entire page that can be displayed when Kibana "has no data", specifically for Analytics. +tags: ['shared-ux', 'component'] +date: 2021-12-28 +--- + +## Description + +This is an Analytics-specific version of `KibanaNoDataPage`, which defaults most of the fields to give a consistent set of terms for Analytics solutions. + +## EUI Promotion Status + +This component is not currently considered for promotion to EUI. diff --git a/packages/shared-ux/page/analytics_no_data/jest.config.js b/packages/shared-ux/page/analytics_no_data/jest.config.js new file mode 100644 index 0000000000000..76067f82881f7 --- /dev/null +++ b/packages/shared-ux/page/analytics_no_data/jest.config.js @@ -0,0 +1,13 @@ +/* + * 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. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../..', + roots: ['/packages/shared-ux/page/analytics_no_data'], +}; diff --git a/packages/shared-ux/page/analytics_no_data/package.json b/packages/shared-ux/page/analytics_no_data/package.json new file mode 100644 index 0000000000000..e9977444fb94e --- /dev/null +++ b/packages/shared-ux/page/analytics_no_data/package.json @@ -0,0 +1,8 @@ +{ + "name": "@kbn/shared-ux-page-analytics-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/page/analytics_no_data/src/__snapshots__/analytics_no_data_page.component.test.tsx.snap b/packages/shared-ux/page/analytics_no_data/src/__snapshots__/analytics_no_data_page.component.test.tsx.snap new file mode 100644 index 0000000000000..be6fd3c45744e --- /dev/null +++ b/packages/shared-ux/page/analytics_no_data/src/__snapshots__/analytics_no_data_page.component.test.tsx.snap @@ -0,0 +1,157 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AnalyticsNoDataPageComponent renders correctly 1`] = ` + + + + } + > + +
+ + + +
+
+
+
+
+
+`; diff --git a/packages/shared-ux/page/analytics_no_data/src/analytics_no_data_page.component.test.tsx b/packages/shared-ux/page/analytics_no_data/src/analytics_no_data_page.component.test.tsx new file mode 100644 index 0000000000000..0f18710197991 --- /dev/null +++ b/packages/shared-ux/page/analytics_no_data/src/analytics_no_data_page.component.test.tsx @@ -0,0 +1,35 @@ +/* + * 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 { mountWithIntl } from '@kbn/test-jest-helpers'; +import { KibanaNoDataPage } from '@kbn/shared-ux-components'; +import { AnalyticsNoDataPage } from './analytics_no_data_page.component'; + +describe('AnalyticsNoDataPageComponent', () => { + const onDataViewCreated = jest.fn(); + + it('renders correctly', () => { + const component = mountWithIntl( + + ); + expect(component).toMatchSnapshot(); + + expect(component.find(KibanaNoDataPage).length).toBe(1); + + const noDataConfig = component.find(KibanaNoDataPage).props().noDataConfig; + expect(noDataConfig.solution).toEqual('Analytics'); + expect(noDataConfig.pageTitle).toEqual('Welcome to Analytics!'); + expect(noDataConfig.logo).toEqual('logoKibana'); + expect(noDataConfig.docsLink).toEqual('http://www.test.com'); + expect(noDataConfig.action.elasticAgent).not.toBeNull(); + }); +}); diff --git a/packages/shared-ux/page/analytics_no_data/src/analytics_no_data_page.component.tsx b/packages/shared-ux/page/analytics_no_data/src/analytics_no_data_page.component.tsx new file mode 100644 index 0000000000000..31051328641f4 --- /dev/null +++ b/packages/shared-ux/page/analytics_no_data/src/analytics_no_data_page.component.tsx @@ -0,0 +1,58 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { KibanaNoDataPage } from '@kbn/shared-ux-components'; + +/** + * Props for the pure component. + */ +export interface Props { + kibanaGuideDocLink: string; + onDataViewCreated: (dataView: unknown) => void; +} + +const solution = i18n.translate('sharedUXPackages.noDataConfig.analytics', { + defaultMessage: 'Analytics', +}); + +const pageTitle = i18n.translate('sharedUXPackages.noDataConfig.analyticsPageTitle', { + defaultMessage: 'Welcome to Analytics!', +}); + +const addIntegrationsTitle = i18n.translate('sharedUXPackages.noDataConfig.addIntegrationsTitle', { + defaultMessage: 'Add integrations', +}); + +const addIntegrationsDescription = i18n.translate( + 'sharedUXPackages.noDataConfig.addIntegrationsDescription', + { + defaultMessage: 'Use Elastic Agent to collect data and build out Analytics solutions.', + } +); + +/** + * A pure component of an entire page that can be displayed when Kibana "has no data", specifically for Analytics. + */ +export const AnalyticsNoDataPage = ({ kibanaGuideDocLink, onDataViewCreated }: Props) => { + const noDataConfig = { + solution, + pageTitle, + logo: 'logoKibana', + action: { + elasticAgent: { + title: addIntegrationsTitle, + description: addIntegrationsDescription, + 'data-test-subj': 'kbnOverviewAddIntegrations', + }, + }, + docsLink: kibanaGuideDocLink, + }; + + return ; +}; 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 new file mode 100644 index 0000000000000..8471cdf9546d2 --- /dev/null +++ b/packages/shared-ux/page/analytics_no_data/src/analytics_no_data_page.stories.tsx @@ -0,0 +1,61 @@ +/* + * 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 { action } from '@storybook/addon-actions'; +import { servicesFactory, DataServiceFactoryConfig } from '@kbn/shared-ux-storybook'; + +import { AnalyticsNoDataPage as Component } from './analytics_no_data_page'; +import { AnalyticsNoDataPageProvider, Services } from './services'; +import mdx from '../README.mdx'; + +export default { + title: 'Analytics No Data Page', + description: 'An Analytics-specific version of KibanaNoDataPage.', + parameters: { + docs: { + page: mdx, + }, + }, +}; + +type Params = Pick; + +export const AnalyticsNoDataPage = (params: Params) => { + // Workaround to leverage the services package. + const { application, data, docLinks, editors, http, permissions, platform } = + servicesFactory(params); + + const services: Services = { + ...application, + ...data, + ...docLinks, + ...editors, + ...http, + ...permissions, + ...platform, + kibanaGuideDocLink: 'Kibana guide', + }; + + return ( + + + + ); +}; + +AnalyticsNoDataPage.argTypes = { + hasESData: { + control: 'boolean', + defaultValue: false, + }, + hasUserDataView: { + control: 'boolean', + defaultValue: false, + }, +}; diff --git a/packages/shared-ux/page/analytics_no_data/src/analytics_no_data_page.test.tsx b/packages/shared-ux/page/analytics_no_data/src/analytics_no_data_page.test.tsx new file mode 100644 index 0000000000000..e091cac70d32b --- /dev/null +++ b/packages/shared-ux/page/analytics_no_data/src/analytics_no_data_page.test.tsx @@ -0,0 +1,50 @@ +/* + * 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 { mountWithIntl } from '@kbn/test-jest-helpers'; +import { mockServicesFactory } from '@kbn/shared-ux-services'; + +import { Services, AnalyticsNoDataPageProvider } from './services'; +import { AnalyticsNoDataPage as Component } from './analytics_no_data_page.component'; +import { AnalyticsNoDataPage } from './analytics_no_data_page'; + +describe('AnalyticsNoDataPage', () => { + const onDataViewCreated = jest.fn(); + + // Workaround to leverage the services package. + const { application, data, docLinks, editors, http, permissions, platform } = + mockServicesFactory(); + + const services: Services = { + ...application, + ...data, + ...docLinks, + ...editors, + ...http, + ...permissions, + ...platform, + kibanaGuideDocLink: 'Kibana guide', + }; + + afterAll(() => { + jest.resetAllMocks(); + }); + + it('renders correctly', async () => { + const component = mountWithIntl( + + + + ); + + expect(component.find(Component).length).toBe(1); + expect(component.find(Component).props().kibanaGuideDocLink).toBe(services.kibanaGuideDocLink); + expect(component.find(Component).props().onDataViewCreated).toBe(onDataViewCreated); + }); +}); diff --git a/packages/shared-ux/page/analytics_no_data/src/analytics_no_data_page.tsx b/packages/shared-ux/page/analytics_no_data/src/analytics_no_data_page.tsx new file mode 100644 index 0000000000000..141f607a6257e --- /dev/null +++ b/packages/shared-ux/page/analytics_no_data/src/analytics_no_data_page.tsx @@ -0,0 +1,39 @@ +/* + * 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 { LegacyServicesProvider, getLegacyServices } from './legacy_services'; +import { useServices } from './services'; +import { AnalyticsNoDataPage as Component } from './analytics_no_data_page.component'; + +/** + * Props for the `AnalyticsNoDataPage` component. + */ +export interface AnalyticsNoDataPageProps { + onDataViewCreated: (dataView: unknown) => void; +} + +/** + * An entire page that can be displayed when Kibana "has no data", specifically for Analytics. Uses + * services from a provider to provide props to a pure component. + */ +export const AnalyticsNoDataPage = ({ onDataViewCreated }: AnalyticsNoDataPageProps) => { + const services = useServices(); + const { kibanaGuideDocLink } = services; + + return ( + + + + ); +}; diff --git a/packages/shared-ux/page/analytics_no_data/src/index.ts b/packages/shared-ux/page/analytics_no_data/src/index.ts new file mode 100644 index 0000000000000..7b87084f745ef --- /dev/null +++ b/packages/shared-ux/page/analytics_no_data/src/index.ts @@ -0,0 +1,27 @@ +/* + * 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 { withSuspense } from '@kbn/shared-ux-utility'; + +export { AnalyticsNoDataPageProvider, AnalyticsNoDataPageKibanaProvider } from './services'; + +/** + * Lazy-loaded connected component. Must be wrapped in `React.Suspense`. + */ +export const LazyAnalyticsNoDataPage = React.lazy(() => + import('./analytics_no_data_page').then(({ AnalyticsNoDataPage }) => ({ + default: AnalyticsNoDataPage, + })) +); + +/** + * An entire page that can be displayed when Kibana "has no data", specifically for Analytics. + * Requires a Provider for relevant services. + */ +export const AnalyticsNoDataPage = withSuspense(LazyAnalyticsNoDataPage); diff --git a/packages/shared-ux/page/analytics_no_data/src/legacy_services.tsx b/packages/shared-ux/page/analytics_no_data/src/legacy_services.tsx new file mode 100644 index 0000000000000..3d690e56e0d23 --- /dev/null +++ b/packages/shared-ux/page/analytics_no_data/src/legacy_services.tsx @@ -0,0 +1,49 @@ +/* + * 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 { SharedUxServicesProvider as LegacyServicesProvider } from '@kbn/shared-ux-services'; +export type { SharedUxServices as LegacyServices } from '@kbn/shared-ux-services'; + +import { SharedUxServices as LegacyServices } from '@kbn/shared-ux-services'; +import { Services } from './services'; + +/** + * This list is temporary, a stop-gap as we migrate to a package-based architecture, where + * services are not collected in a single package. In order to make the transition, this + * interface is intentionally "flat". + * + * Expect this list to dwindle to zero as `@kbn/shared-ux-components` are migrated to their + * own packages, (and `@kbn/shared-ux-services` is removed). + */ +export const getLegacyServices = (services: Services): LegacyServices => ({ + application: { + currentAppId$: services.currentAppId$, + navigateToUrl: services.navigateToUrl, + }, + data: { + hasESData: services.hasESData, + hasDataView: services.hasDataView, + hasUserDataView: services.hasUserDataView, + }, + docLinks: { + dataViewsDocLink: services.dataViewsDocLink, + }, + editors: { + openDataViewEditor: services.openDataViewEditor, + }, + http: { + addBasePath: services.addBasePath, + }, + permissions: { + canAccessFleet: services.canAccessFleet, + canCreateNewDataView: services.canCreateNewDataView, + }, + platform: { + setIsFullscreen: services.setIsFullscreen, + }, +}); diff --git a/packages/shared-ux/page/analytics_no_data/src/services.tsx b/packages/shared-ux/page/analytics_no_data/src/services.tsx new file mode 100644 index 0000000000000..70ba29ed2f648 --- /dev/null +++ b/packages/shared-ux/page/analytics_no_data/src/services.tsx @@ -0,0 +1,162 @@ +/* + * 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 { Observable } from 'rxjs'; + +/** + * TODO: `DataView` is a class exported by `src/plugins/data_views/public`. Since this service + * is contained in this package-- and packages can only depend on other packages and never on + * plugins-- we have to set this to `unknown`. If and when `DataView` is exported from a + * stateless package, we can remove this. + * + * @see: https://github.com/elastic/kibana/issues/127695 + */ +type DataView = unknown; + +/** + * A subset of the `DataViewEditorOptions` interface relevant to this component. + * + * @see: src/plugins/data_view_editor/public/types.ts + */ +interface DataViewEditorOptions { + /** Handler to be invoked when the Data View Editor completes a save operation. */ + onSave: (dataView: DataView) => void; +} + +/** + * A list of Services that are consumed by this component. + * + * This list is temporary, a stopgap as we migrate to a package-based architecture, where + * services are not collected in a single package. In order to make the transition, this + * interface is intentionally "flat". + * + * Expect this list to dwindle to zero as `@kbn/shared-ux-components` are migrated to their + * own packages, (and `@kbn/shared-ux-services` is removed). + */ +export interface Services { + addBasePath: (url: string) => string; + canAccessFleet: boolean; + canCreateNewDataView: boolean; + currentAppId$: Observable; + dataViewsDocLink: string; + hasDataView: () => Promise; + hasESData: () => Promise; + hasUserDataView: () => Promise; + kibanaGuideDocLink: string; + navigateToUrl: (url: string) => Promise; + openDataViewEditor: (options: DataViewEditorOptions) => () => void; + setIsFullscreen: (isFullscreen: boolean) => void; +} + +const AnalyticsNoDataPageContext = React.createContext(null); + +/** + * A Context Provider that provides services to the component. + */ +export const AnalyticsNoDataPageProvider: FC = ({ children, ...services }) => { + return ( + + {children} + + ); +}; + +/** + * An interface containing a collection of Kibana plugins and services required to + * render this component and its dependencies. + */ +export interface AnalyticsNoDataPageKibanaDependencies { + coreStart: { + application: { + capabilities: { + navLinks: { + integrations: boolean; + }; + }; + currentAppId$: Observable; + navigateToUrl: (url: string) => Promise; + }; + chrome: { + setIsVisible: (isVisible: boolean) => void; + }; + docLinks: { + links: { + indexPatterns: { + introduction: string; + }; + kibana: { + guide: string; + }; + }; + }; + http: { + basePath: { + prepend: (url: string) => string; + }; + }; + }; + dataViews: { + hasData: { + hasDataView: () => Promise; + hasESData: () => Promise; + hasUserDataView: () => Promise; + }; + }; + dataViewEditor: { + openEditor: (options: DataViewEditorOptions) => () => void; + userPermissions: { + editDataView: () => boolean; + }; + }; +} + +/** + * Kibana-specific Provider that maps dependencies to services. + */ +export const AnalyticsNoDataPageKibanaProvider: FC = ({ + children, + ...dependencies +}) => { + const { coreStart, dataViewEditor, dataViews } = dependencies; + const value: Services = { + addBasePath: coreStart.http.basePath.prepend, + canAccessFleet: coreStart.application.capabilities.navLinks.integrations, + canCreateNewDataView: dataViewEditor.userPermissions.editDataView(), + currentAppId$: coreStart.application.currentAppId$, + dataViewsDocLink: coreStart.docLinks.links.indexPatterns?.introduction, + hasDataView: dataViews.hasData.hasDataView, + hasESData: dataViews.hasData.hasESData, + hasUserDataView: dataViews.hasData.hasUserDataView, + kibanaGuideDocLink: coreStart.docLinks.links.kibana.guide, + navigateToUrl: coreStart.application.navigateToUrl, + openDataViewEditor: dataViewEditor.openEditor, + setIsFullscreen: (isVisible: boolean) => coreStart.chrome.setIsVisible(isVisible), + }; + + return ( + + {children} + + ); +}; + +/** + * React hook for accessing pre-wired services. + */ +export function useServices() { + const context = useContext(AnalyticsNoDataPageContext); + + if (!context) { + throw new Error( + 'AnalyticsNoDataPageContext is missing. Ensure your component or React root is wrapped with AnalyticsNoDataPageContext.' + ); + } + + return context; +} diff --git a/packages/shared-ux/page/analytics_no_data/tsconfig.json b/packages/shared-ux/page/analytics_no_data/tsconfig.json new file mode 100644 index 0000000000000..573ad07325100 --- /dev/null +++ b/packages/shared-ux/page/analytics_no_data/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": "src", + "stripInternal": false, + "types": [ + "jest", + "node", + "react", + "@kbn/ambient-ui-types", + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/yarn.lock b/yarn.lock index f770f30d3687d..ef4d936085940 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3220,6 +3220,10 @@ version "0.0.0" uid "" +"@kbn/shared-ux-page-analytics-no-data@link:bazel-bin/packages/shared-ux/page/analytics_no_data": + version "0.0.0" + uid "" + "@kbn/shared-ux-services@link:bazel-bin/packages/kbn-shared-ux-services": version "0.0.0" uid "" @@ -6316,6 +6320,10 @@ version "0.0.0" uid "" +"@types/kbn__shared-ux-page-analytics-no-data@link:bazel-bin/packages/shared-ux/page/analytics_no_data/npm_module_types": + version "0.0.0" + uid "" + "@types/kbn__shared-ux-services@link:bazel-bin/packages/kbn-shared-ux-services/npm_module_types": version "0.0.0" uid ""