diff --git a/.buildkite/scripts/steps/cloud/build_and_deploy.sh b/.buildkite/scripts/steps/cloud/build_and_deploy.sh index 8b202bea9fc84..2bb9bc90e88da 100755 --- a/.buildkite/scripts/steps/cloud/build_and_deploy.sh +++ b/.buildkite/scripts/steps/cloud/build_and_deploy.sh @@ -32,6 +32,10 @@ node scripts/build \ --skip-docker-ubuntu \ --skip-docker-contexts +ELASTICSEARCH_MANIFEST_URL="https://storage.googleapis.com/kibana-ci-es-snapshots-daily/$(jq -r '.version' package.json)/manifest-latest-verified.json" +ELASTICSEARCH_SHA=$(curl -s $ELASTICSEARCH_MANIFEST_URL | jq -r '.sha') +ELASTICSEARCH_CLOUD_IMAGE="docker.elastic.co/kibana-ci/elasticsearch-cloud:$VERSION-$ELASTICSEARCH_SHA" + CLOUD_IMAGE=$(docker images --format "{{.Repository}}:{{.Tag}}" docker.elastic.co/kibana-ci/kibana-cloud) CLOUD_DEPLOYMENT_NAME="kibana-pr-$BUILDKITE_PULL_REQUEST" @@ -40,6 +44,7 @@ JSON_FILE=$(mktemp --suffix ".json") if [ -z "${CLOUD_DEPLOYMENT_ID}" ]; then jq ' .resources.kibana[0].plan.kibana.docker_image = "'$CLOUD_IMAGE'" | + .resources.elasticsearch[0].plan.elasticsearch.docker_image = "'$ELASTICSEARCH_CLOUD_IMAGE'" | .name = "'$CLOUD_DEPLOYMENT_NAME'" | .resources.kibana[0].plan.kibana.version = "'$VERSION'" | .resources.elasticsearch[0].plan.elasticsearch.version = "'$VERSION'" | @@ -70,6 +75,7 @@ if [ -z "${CLOUD_DEPLOYMENT_ID}" ]; then else ecctl deployment show "$CLOUD_DEPLOYMENT_ID" --generate-update-payload | jq ' .resources.kibana[0].plan.kibana.docker_image = "'$CLOUD_IMAGE'" | + .resources.elasticsearch[0].plan.elasticsearch.docker_image = "'$ELASTICSEARCH_CLOUD_IMAGE'" | (.. | select(.version? != null).version) = "'$VERSION'" ' > /tmp/deploy.json ecctl deployment update "$CLOUD_DEPLOYMENT_ID" --track --output json --file /tmp/deploy.json &> "$JSON_FILE" @@ -87,7 +93,9 @@ cat << EOF | buildkite-agent annotate --style "info" --context cloud Credentials: \`vault read secret/kibana-issues/dev/cloud-deploy/$CLOUD_DEPLOYMENT_NAME\` - Image: $CLOUD_IMAGE + Kibana image: \`$CLOUD_IMAGE\` + + Elasticsearch image: \`$ELASTICSEARCH_CLOUD_IMAGE\` EOF buildkite-agent meta-data set pr_comment:deploy_cloud:head "* [Cloud Deployment](${CLOUD_DEPLOYMENT_KIBANA_URL})" diff --git a/.i18nrc.json b/.i18nrc.json index eeb2578ef3472..402932902f249 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -60,6 +60,7 @@ "server": "src/legacy/server", "share": "src/plugins/share", "sharedUX": "src/plugins/shared_ux", + "sharedUXComponents": "packages/kbn-shared-ux-components/src", "statusPage": "src/legacy/core_plugins/status_page", "telemetry": ["src/plugins/telemetry", "src/plugins/telemetry_management_section"], "timelion": ["src/plugins/vis_types/timelion"], diff --git a/docs/maps/import-geospatial-data.asciidoc b/docs/maps/import-geospatial-data.asciidoc index 7a35b7d1df599..3746b21437a44 100644 --- a/docs/maps/import-geospatial-data.asciidoc +++ b/docs/maps/import-geospatial-data.asciidoc @@ -6,9 +6,6 @@ To import geospatical data into the Elastic Stack, the data must be indexed as { Geospatial data comes in many formats. Choose an import tool based on the format of your geospatial data. -TIP: When you upload files in {kib}, there is a file size -limit, which is configurable in <>. - [discrete] [[import-geospatial-privileges]] === Security privileges diff --git a/docs/settings/fleet-settings.asciidoc b/docs/settings/fleet-settings.asciidoc index 1aa6b92ffa090..5ddf45887a530 100644 --- a/docs/settings/fleet-settings.asciidoc +++ b/docs/settings/fleet-settings.asciidoc @@ -81,7 +81,7 @@ Optional properties are: `namespace`:: String identifying this policy's namespace. `monitoring_enabled`:: List of keywords that specify the monitoring data to collect. Valid values include `['logs']`, `['metrics']`, and `['logs', 'metrics']`. - `is_managed`:: If `true`, this policy is editable by the user and can only + `is_managed`:: If `true`, this policy is not editable by the user and can only be changed by updating the {kib} config. `is_default`:: If `true`, this policy is the default agent policy. `is_default_fleet_server`:: If `true`, this policy is the default {fleet-server} agent policy. diff --git a/docs/user/dashboard/vega-reference.asciidoc b/docs/user/dashboard/vega-reference.asciidoc index b9fdf0c9a7ec5..b593eacf703fb 100644 --- a/docs/user/dashboard/vega-reference.asciidoc +++ b/docs/user/dashboard/vega-reference.asciidoc @@ -351,6 +351,9 @@ a configuration option for changing the tooltip position and padding: *Vega* can load data from any URL. To enable, set `vis_type_vega.enableExternalUrls: true` in `kibana.yml`, then restart {kib}. +The files that the external URLs load must allow https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS[CORS]. +The remote URL must include `Access-Control-Allow-Origin`, which allows requests from the {kib} URL. + You can make the current time range part of the external as a millisecond timestamp by using the placeholders `%timefilter_min%` and `%timefilter_max%`, e.g. `http://example.com?min=%timefilter_min%`. [float] diff --git a/package.json b/package.json index 7cd642f0bee4a..20a0f50821be1 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "@elastic/datemath": "link:bazel-bin/packages/elastic-datemath", "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@8.2.0-canary.1", "@elastic/ems-client": "8.1.0", - "@elastic/eui": "48.1.1", + "@elastic/eui": "51.1.0", "@elastic/filesaver": "1.1.2", "@elastic/node-crypto": "1.2.1", "@elastic/numeral": "^2.5.1", @@ -167,6 +167,10 @@ "@kbn/securitysolution-utils": "link:bazel-bin/packages/kbn-securitysolution-utils", "@kbn/server-http-tools": "link:bazel-bin/packages/kbn-server-http-tools", "@kbn/server-route-repository": "link:bazel-bin/packages/kbn-server-route-repository", + "@kbn/shared-ux-components": "link:bazel-bin/packages/kbn-shared-ux-components", + "@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", "@kbn/std": "link:bazel-bin/packages/kbn-std", "@kbn/timelion-grammar": "link:bazel-bin/packages/kbn-timelion-grammar", "@kbn/tinymath": "link:bazel-bin/packages/kbn-tinymath", @@ -196,6 +200,10 @@ "@turf/helpers": "6.0.1", "@turf/length": "^6.0.2", "@types/jsonwebtoken": "^8.5.6", + "@types/kbn__shared-ux-components": "link:bazel-bin/packages/kbn-shared-ux-components/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", "@types/moment-duration-format": "^2.2.3", "JSONStream": "1.3.5", "abort-controller": "^3.0.0", diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index f01042cecfae9..e880df5f55782 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -66,6 +66,10 @@ filegroup( "//packages/kbn-securitysolution-utils:build", "//packages/kbn-server-http-tools:build", "//packages/kbn-server-route-repository:build", + "//packages/kbn-shared-ux-components:build", + "//packages/kbn-shared-ux-services:build", + "//packages/kbn-shared-ux-storybook:build", + "//packages/kbn-shared-ux-utility:build", "//packages/kbn-spec-to-console:build", "//packages/kbn-std:build", "//packages/kbn-storybook:build", @@ -139,6 +143,10 @@ filegroup( "//packages/kbn-securitysolution-utils:build_types", "//packages/kbn-server-http-tools:build_types", "//packages/kbn-server-route-repository:build_types", + "//packages/kbn-shared-ux-components:build_types", + "//packages/kbn-shared-ux-services:build_types", + "//packages/kbn-shared-ux-storybook:build_types", + "//packages/kbn-shared-ux-utility:build_types", "//packages/kbn-std:build_types", "//packages/kbn-storybook:build_types", "//packages/kbn-telemetry-tools:build_types", diff --git a/packages/kbn-es-query/src/index.ts b/packages/kbn-es-query/src/index.ts index 232df8ce509eb..3363bd826088f 100644 --- a/packages/kbn-es-query/src/index.ts +++ b/packages/kbn-es-query/src/index.ts @@ -6,12 +6,109 @@ * Side Public License, v 1. */ -export * from './es_query'; -export * from './filters'; -export * from './kuery'; +export type { + BoolQuery, + DataViewBase, + DataViewFieldBase, + EsQueryConfig, + IFieldSubType, + IFieldSubTypeMulti, + IFieldSubTypeNested, +} from './es_query'; + +export type { + CustomFilter, + ExistsFilter, + FieldFilter, + Filter, + FilterCompareOptions, + FilterMeta, + LatLon, + MatchAllFilter, + PhraseFilter, + PhrasesFilter, + Query, + QueryStringFilter, + RangeFilter, + RangeFilterMeta, + RangeFilterParams, + ScriptedPhraseFilter, + ScriptedRangeFilter, +} from './filters'; + +export type { + DslQuery, + FunctionTypeBuildNode, + KueryNode, + KueryParseOptions, + KueryQueryOptions, + NodeTypes, +} from './kuery'; + +export { + buildEsQuery, + buildQueryFromFilters, + decorateQuery, + luceneStringToDsl, + migrateFilter, +} from './es_query'; + +export { + COMPARE_ALL_OPTIONS, + FILTERS, + FilterStateStore, + buildCustomFilter, + buildEmptyFilter, + buildExistsFilter, + buildFilter, + buildPhraseFilter, + buildPhrasesFilter, + buildQueryFilter, + buildRangeFilter, + cleanFilter, + compareFilters, + dedupFilters, + disableFilter, + enableFilter, + getConvertedValueForField, + getFilterField, + getFilterParams, + getPhraseFilterField, + getPhraseFilterValue, + getPhraseScript, + getRangeScript, + isExistsFilter, + isFilter, + isFilterDisabled, + isFilterPinned, + isFilters, + isMatchAllFilter, + isPhraseFilter, + isPhrasesFilter, + isQueryStringFilter, + isRangeFilter, + isScriptedPhraseFilter, + isScriptedRangeFilter, + onlyDisabledFiltersChanged, + pinFilter, + toggleFilterDisabled, + toggleFilterNegated, + toggleFilterPinned, + uniqFilters, + unpinFilter, +} from './filters'; + +export { + KQLSyntaxError, + fromKueryExpression, + nodeBuilder, + nodeTypes, + toElasticsearchQuery, +} from './kuery'; + export { - isDataViewFieldSubtypeMulti, - isDataViewFieldSubtypeNested, getDataViewFieldSubtypeMulti, getDataViewFieldSubtypeNested, + isDataViewFieldSubtypeMulti, + isDataViewFieldSubtypeNested, } from './utils'; diff --git a/packages/kbn-shared-ux-components/BUILD.bazel b/packages/kbn-shared-ux-components/BUILD.bazel new file mode 100644 index 0000000000000..16dfe9e0620e1 --- /dev/null +++ b/packages/kbn-shared-ux-components/BUILD.bazel @@ -0,0 +1,150 @@ +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 = "kbn-shared-ux-components" +PKG_REQUIRE_NAME = "@kbn/shared-ux-components" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + "src/**/*.tsx", + "src/**/*.scss", + "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 = [ + "//packages/kbn-i18n", + "//packages/kbn-i18n-react", + "//packages/kbn-shared-ux-services", + "//packages/kbn-shared-ux-storybook", + "//packages/kbn-shared-ux-utility", + "@npm//@elastic/eui", + "@npm//@emotion/react", + "@npm//@emotion/css", + "@npm//classnames", + "@npm//react-use", + "@npm//react", +] + +# 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 = [ + "//packages/kbn-i18n:npm_module_types", + "//packages/kbn-i18n-react: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", + "@npm//@types/node", + "@npm//@types/jest", + "@npm//@types/react", + "@npm//@types/classnames", + "@npm//@emotion/react", + "@npm//@emotion/css", + "@npm//@elastic/eui", + "@npm//react-use", +] + +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/kbn-shared-ux-components/README.mdx b/packages/kbn-shared-ux-components/README.mdx new file mode 100644 index 0000000000000..8fee1571e5220 --- /dev/null +++ b/packages/kbn-shared-ux-components/README.mdx @@ -0,0 +1,10 @@ +--- +id: kibSharedUXComponents +slug: /kibana-dev-docs/shared-ux/packages/kbn-shared-ux-components +title: Shared UX Components +summary: +date: 2022-03-11 +tags: ['kibana', 'dev', 'sharedUX'] +--- + +> TODO diff --git a/packages/kbn-shared-ux-components/jest.config.js b/packages/kbn-shared-ux-components/jest.config.js new file mode 100644 index 0000000000000..c2ac8c3a57106 --- /dev/null +++ b/packages/kbn-shared-ux-components/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/kbn-shared-ux-components'], +}; diff --git a/packages/kbn-shared-ux-components/package.json b/packages/kbn-shared-ux-components/package.json new file mode 100644 index 0000000000000..948df7fadd712 --- /dev/null +++ b/packages/kbn-shared-ux-components/package.json @@ -0,0 +1,8 @@ +{ + "name": "@kbn/shared-ux-components", + "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/src/plugins/shared_ux/public/components/empty_state/assets/data_view_illustration.tsx b/packages/kbn-shared-ux-components/src/empty_state/assets/data_view_illustration.tsx similarity index 100% rename from src/plugins/shared_ux/public/components/empty_state/assets/data_view_illustration.tsx rename to packages/kbn-shared-ux-components/src/empty_state/assets/data_view_illustration.tsx diff --git a/src/plugins/shared_ux/public/components/empty_state/assets/index.tsx b/packages/kbn-shared-ux-components/src/empty_state/assets/index.tsx similarity index 93% rename from src/plugins/shared_ux/public/components/empty_state/assets/index.tsx rename to packages/kbn-shared-ux-components/src/empty_state/assets/index.tsx index c234cdf40055b..129bbbf3b202d 100644 --- a/src/plugins/shared_ux/public/components/empty_state/assets/index.tsx +++ b/packages/kbn-shared-ux-components/src/empty_state/assets/index.tsx @@ -10,7 +10,7 @@ import React from 'react'; import { EuiLoadingSpinner } from '@elastic/eui'; -import { withSuspense } from '../../utility'; +import { withSuspense } from '@kbn/shared-ux-utility'; export const LazyDataViewIllustration = React.lazy(() => import('../assets/data_view_illustration').then(({ DataViewIllustration }) => ({ diff --git a/src/plugins/shared_ux/public/components/empty_state/index.tsx b/packages/kbn-shared-ux-components/src/empty_state/index.tsx similarity index 100% rename from src/plugins/shared_ux/public/components/empty_state/index.tsx rename to packages/kbn-shared-ux-components/src/empty_state/index.tsx diff --git a/src/plugins/shared_ux/public/components/empty_state/no_data_views/__snapshots__/documentation_link.test.tsx.snap b/packages/kbn-shared-ux-components/src/empty_state/no_data_views/__snapshots__/documentation_link.test.tsx.snap similarity index 83% rename from src/plugins/shared_ux/public/components/empty_state/no_data_views/__snapshots__/documentation_link.test.tsx.snap rename to packages/kbn-shared-ux-components/src/empty_state/no_data_views/__snapshots__/documentation_link.test.tsx.snap index 5526b78bceb73..e84b997d8df87 100644 --- a/src/plugins/shared_ux/public/components/empty_state/no_data_views/__snapshots__/documentation_link.test.tsx.snap +++ b/packages/kbn-shared-ux-components/src/empty_state/no_data_views/__snapshots__/documentation_link.test.tsx.snap @@ -10,7 +10,7 @@ exports[` is rendered correctly 1`] = ` > @@ -26,7 +26,7 @@ exports[` is rendered correctly 1`] = ` > diff --git a/src/plugins/shared_ux/public/components/empty_state/no_data_views/documentation_link.test.tsx b/packages/kbn-shared-ux-components/src/empty_state/no_data_views/documentation_link.test.tsx similarity index 100% rename from src/plugins/shared_ux/public/components/empty_state/no_data_views/documentation_link.test.tsx rename to packages/kbn-shared-ux-components/src/empty_state/no_data_views/documentation_link.test.tsx diff --git a/src/plugins/shared_ux/public/components/empty_state/no_data_views/documentation_link.tsx b/packages/kbn-shared-ux-components/src/empty_state/no_data_views/documentation_link.tsx similarity index 89% rename from src/plugins/shared_ux/public/components/empty_state/no_data_views/documentation_link.tsx rename to packages/kbn-shared-ux-components/src/empty_state/no_data_views/documentation_link.tsx index 4ac07899fef5f..3b3e742ea74ce 100644 --- a/src/plugins/shared_ux/public/components/empty_state/no_data_views/documentation_link.tsx +++ b/packages/kbn-shared-ux-components/src/empty_state/no_data_views/documentation_link.tsx @@ -20,7 +20,7 @@ export function DocumentationLink({ href }: Props) {
@@ -29,7 +29,7 @@ export function DocumentationLink({ href }: Props) {
diff --git a/src/plugins/shared_ux/public/components/empty_state/no_data_views/index.tsx b/packages/kbn-shared-ux-components/src/empty_state/no_data_views/index.tsx similarity index 100% rename from src/plugins/shared_ux/public/components/empty_state/no_data_views/index.tsx rename to packages/kbn-shared-ux-components/src/empty_state/no_data_views/index.tsx diff --git a/src/plugins/shared_ux/public/components/empty_state/no_data_views/no_data_views.component.test.tsx b/packages/kbn-shared-ux-components/src/empty_state/no_data_views/no_data_views.component.test.tsx similarity index 100% rename from src/plugins/shared_ux/public/components/empty_state/no_data_views/no_data_views.component.test.tsx rename to packages/kbn-shared-ux-components/src/empty_state/no_data_views/no_data_views.component.test.tsx diff --git a/src/plugins/shared_ux/public/components/empty_state/no_data_views/no_data_views.component.tsx b/packages/kbn-shared-ux-components/src/empty_state/no_data_views/no_data_views.component.tsx similarity index 89% rename from src/plugins/shared_ux/public/components/empty_state/no_data_views/no_data_views.component.tsx rename to packages/kbn-shared-ux-components/src/empty_state/no_data_views/no_data_views.component.tsx index bfab91ef03b26..bffa7c2a5269c 100644 --- a/src/plugins/shared_ux/public/components/empty_state/no_data_views/no_data_views.component.tsx +++ b/packages/kbn-shared-ux-components/src/empty_state/no_data_views/no_data_views.component.tsx @@ -23,7 +23,7 @@ export interface Props { emptyPromptColor?: EuiEmptyPromptProps['color']; } -const createDataViewText = i18n.translate('sharedUX.noDataViewsPage.addDataViewText', { +const createDataViewText = i18n.translate('sharedUXComponents.noDataViewsPage.addDataViewText', { defaultMessage: 'Create Data View', }); @@ -62,12 +62,12 @@ export const NoDataViews = ({ title={


@@ -75,7 +75,7 @@ export const NoDataViews = ({ body={

is rendered 1`] = ` } docLinks={ Object { - "dataViewsDocsLink": "dummy link", + "dataViewsDocLink": "dummy link", } } editors={ @@ -134,5 +134,5 @@ exports[` is rendered 1`] = ` - + `; diff --git a/src/plugins/shared_ux/public/components/exit_full_screen_button/exit_full_screen_button.component.tsx b/packages/kbn-shared-ux-components/src/exit_full_screen_button/exit_full_screen_button.component.tsx similarity index 87% rename from src/plugins/shared_ux/public/components/exit_full_screen_button/exit_full_screen_button.component.tsx rename to packages/kbn-shared-ux-components/src/exit_full_screen_button/exit_full_screen_button.component.tsx index 311f2236c34a0..6c037cc5f65cb 100644 --- a/src/plugins/shared_ux/public/components/exit_full_screen_button/exit_full_screen_button.component.tsx +++ b/packages/kbn-shared-ux-components/src/exit_full_screen_button/exit_full_screen_button.component.tsx @@ -21,13 +21,19 @@ import cx from 'classnames'; import './exit_full_screen_button.scss'; -const text = i18n.translate('sharedUX.exitFullScreenButton.exitFullScreenModeButtonText', { - defaultMessage: 'Exit full screen', -}); +const text = i18n.translate( + 'sharedUXComponents.exitFullScreenButton.exitFullScreenModeButtonText', + { + defaultMessage: 'Exit full screen', + } +); -const description = i18n.translate('sharedUX.exitFullScreenButton.fullScreenModeDescription', { - defaultMessage: 'In full screen mode, press ESC to exit.', -}); +const description = i18n.translate( + 'sharedUXComponents.exitFullScreenButton.fullScreenModeDescription', + { + defaultMessage: 'In full screen mode, press ESC to exit.', + } +); /** * Props for the Exit Full Screen button component. diff --git a/src/plugins/shared_ux/public/components/exit_full_screen_button/exit_full_screen_button.mdx b/packages/kbn-shared-ux-components/src/exit_full_screen_button/exit_full_screen_button.mdx similarity index 100% rename from src/plugins/shared_ux/public/components/exit_full_screen_button/exit_full_screen_button.mdx rename to packages/kbn-shared-ux-components/src/exit_full_screen_button/exit_full_screen_button.mdx diff --git a/src/plugins/shared_ux/public/components/exit_full_screen_button/exit_full_screen_button.scss b/packages/kbn-shared-ux-components/src/exit_full_screen_button/exit_full_screen_button.scss similarity index 100% rename from src/plugins/shared_ux/public/components/exit_full_screen_button/exit_full_screen_button.scss rename to packages/kbn-shared-ux-components/src/exit_full_screen_button/exit_full_screen_button.scss diff --git a/src/plugins/shared_ux/public/components/exit_full_screen_button/exit_full_screen_button.stories.tsx b/packages/kbn-shared-ux-components/src/exit_full_screen_button/exit_full_screen_button.stories.tsx similarity index 100% rename from src/plugins/shared_ux/public/components/exit_full_screen_button/exit_full_screen_button.stories.tsx rename to packages/kbn-shared-ux-components/src/exit_full_screen_button/exit_full_screen_button.stories.tsx diff --git a/src/plugins/shared_ux/public/components/exit_full_screen_button/exit_full_screen_button.test.tsx b/packages/kbn-shared-ux-components/src/exit_full_screen_button/exit_full_screen_button.test.tsx similarity index 89% rename from src/plugins/shared_ux/public/components/exit_full_screen_button/exit_full_screen_button.test.tsx rename to packages/kbn-shared-ux-components/src/exit_full_screen_button/exit_full_screen_button.test.tsx index dc634810a5794..da205ddfbe377 100644 --- a/src/plugins/shared_ux/public/components/exit_full_screen_button/exit_full_screen_button.test.tsx +++ b/packages/kbn-shared-ux-components/src/exit_full_screen_button/exit_full_screen_button.test.tsx @@ -10,18 +10,21 @@ import React from 'react'; import { mount as enzymeMount, ReactWrapper } from 'enzyme'; import { keys } from '@elastic/eui'; -import { ServicesProvider, SharedUXServices } from '../../services'; -import { servicesFactory } from '../../services/mocks'; +import { + SharedUxServicesProvider, + SharedUxServices, + mockServicesFactory, +} from '@kbn/shared-ux-services'; import { ExitFullScreenButton } from './exit_full_screen_button'; describe('', () => { - let services: SharedUXServices; + let services: SharedUxServices; let mount: (element: JSX.Element) => ReactWrapper; beforeEach(() => { - services = servicesFactory(); + services = mockServicesFactory(); mount = (element: JSX.Element) => - enzymeMount({element}); + enzymeMount({element}); }); afterEach(() => { diff --git a/src/plugins/shared_ux/public/components/exit_full_screen_button/exit_full_screen_button.tsx b/packages/kbn-shared-ux-components/src/exit_full_screen_button/exit_full_screen_button.tsx similarity index 97% rename from src/plugins/shared_ux/public/components/exit_full_screen_button/exit_full_screen_button.tsx rename to packages/kbn-shared-ux-components/src/exit_full_screen_button/exit_full_screen_button.tsx index 1f0b2f43a6b25..30deaaa86f4c5 100644 --- a/src/plugins/shared_ux/public/components/exit_full_screen_button/exit_full_screen_button.tsx +++ b/packages/kbn-shared-ux-components/src/exit_full_screen_button/exit_full_screen_button.tsx @@ -10,8 +10,9 @@ import React, { useCallback, useEffect } from 'react'; import { useEuiTheme, keys } from '@elastic/eui'; import { css } from '@emotion/react'; +import { usePlatformService } from '@kbn/shared-ux-services'; + import { ExitFullScreenButton as Component } from './exit_full_screen_button.component'; -import { usePlatformService } from '../../services'; /** * Props for the service-enabled Exit Full Screen button component. diff --git a/src/plugins/shared_ux/public/components/exit_full_screen_button/index.ts b/packages/kbn-shared-ux-components/src/exit_full_screen_button/index.ts similarity index 100% rename from src/plugins/shared_ux/public/components/exit_full_screen_button/index.ts rename to packages/kbn-shared-ux-components/src/exit_full_screen_button/index.ts diff --git a/src/plugins/shared_ux/public/components/index.ts b/packages/kbn-shared-ux-components/src/index.ts similarity index 89% rename from src/plugins/shared_ux/public/components/index.ts rename to packages/kbn-shared-ux-components/src/index.ts index 53577e792aaa2..ed95c8dc5d167 100644 --- a/src/plugins/shared_ux/public/components/index.ts +++ b/packages/kbn-shared-ux-components/src/index.ts @@ -7,7 +7,7 @@ */ import React from 'react'; -import { withSuspense } from './utility'; +import { withSuspense } from '@kbn/shared-ux-utility'; /** * The Lazily-loaded `ExitFullScreenButton` component. Consumers should use `React.Suspennse` or the @@ -45,18 +45,18 @@ export const ToolbarButton = withSuspense(LazyToolbarButton); * The Lazily-loaded `NoDataViews` component. Consumers should use `React.Suspennse` or the * `withSuspense` HOC to load this component. */ -export const LazyNoDataViewsPage = React.lazy(() => +export const LazyNoDataViews = React.lazy(() => import('./empty_state/no_data_views').then(({ NoDataViews }) => ({ default: NoDataViews, })) ); /** - * A `NoDataViewsPage` component that is wrapped by the `withSuspense` HOC. This component can - * be used directly by consumers and will load the `LazyNoDataViewsPage` component lazily with + * A `NoDataViews` component that is wrapped by the `withSuspense` HOC. This component can + * be used directly by consumers and will load the `LazyNoDataViews` component lazily with * a predefined fallback and error boundary. */ -export const NoDataViewsPage = withSuspense(LazyNoDataViewsPage); +export const NoDataViews = withSuspense(LazyNoDataViews); /** * The Lazily-loaded `IconButtonGroup` component. Consumers should use `React.Suspennse` or the diff --git a/src/plugins/shared_ux/public/types/mdx.d.ts b/packages/kbn-shared-ux-components/src/mdx.d.ts similarity index 100% rename from src/plugins/shared_ux/public/types/mdx.d.ts rename to packages/kbn-shared-ux-components/src/mdx.d.ts diff --git a/src/plugins/shared_ux/public/components/page_template/index.tsx b/packages/kbn-shared-ux-components/src/page_template/index.tsx similarity index 82% rename from src/plugins/shared_ux/public/components/page_template/index.tsx rename to packages/kbn-shared-ux-components/src/page_template/index.tsx index 0c4fb2e066bfc..adbfdce45be76 100644 --- a/src/plugins/shared_ux/public/components/page_template/index.tsx +++ b/packages/kbn-shared-ux-components/src/page_template/index.tsx @@ -6,4 +6,4 @@ * Side Public License, v 1. */ -export { NoDataCard, ElasticAgentCard } from './no_data_page/no_data_card'; +export { NoDataCard, ElasticAgentCard } from './no_data_page'; diff --git a/src/plugins/shared_ux/.storybook/main.ts b/packages/kbn-shared-ux-components/src/page_template/no_data_page/index.ts similarity index 81% rename from src/plugins/shared_ux/.storybook/main.ts rename to packages/kbn-shared-ux-components/src/page_template/no_data_page/index.ts index 1261fe5a06f69..9b0ee88250422 100644 --- a/src/plugins/shared_ux/.storybook/main.ts +++ b/packages/kbn-shared-ux-components/src/page_template/no_data_page/index.ts @@ -6,6 +6,4 @@ * Side Public License, v 1. */ -import { defaultConfig } from '@kbn/storybook'; - -module.exports = defaultConfig; +export { NoDataCard, ElasticAgentCard } from './no_data_card'; diff --git a/src/plugins/shared_ux/public/components/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 similarity index 100% rename from src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.component.test.tsx.snap rename to packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.component.test.tsx.snap diff --git a/src/plugins/shared_ux/public/components/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 similarity index 99% rename from src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap rename to packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap index dd8ae6993ecc6..76f1beb7ac481 100644 --- a/src/plugins/shared_ux/public/components/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 @@ -5,7 +5,7 @@ exports[`ElasticAgentCard renders 1`] = ` max-width: 400px; } - - + `; diff --git a/src/plugins/shared_ux/public/components/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 similarity index 100% rename from src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/__snapshots__/no_data_card.test.tsx.snap rename to packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/__snapshots__/no_data_card.test.tsx.snap diff --git a/src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/assets/elastic_agent_card.svg b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/assets/elastic_agent_card.svg similarity index 100% rename from src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/assets/elastic_agent_card.svg rename to packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/assets/elastic_agent_card.svg diff --git a/src/plugins/shared_ux/public/components/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 similarity index 100% rename from src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/elastic_agent_card.component.test.tsx rename to packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.component.test.tsx diff --git a/src/plugins/shared_ux/public/components/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 similarity index 86% rename from src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/elastic_agent_card.component.tsx rename to packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.component.tsx index 81b7b6bc61a2d..0bca3929f4c2d 100644 --- a/src/plugins/shared_ux/public/components/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 @@ -22,25 +22,28 @@ export type ElasticAgentCardComponentProps = ElasticAgentCardProps & { }; const noPermissionTitle = i18n.translate( - 'sharedUX.noDataPage.elasticAgentCard.noPermission.title', + 'sharedUXComponents.noDataPage.elasticAgentCard.noPermission.title', { defaultMessage: `Contact your administrator`, } ); const noPermissionDescription = i18n.translate( - 'sharedUX.noDataPage.elasticAgentCard.noPermission.description', + '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('sharedUX.noDataPage.elasticAgentCard.title', { - defaultMessage: 'Add Elastic Agent', -}); +const elasticAgentCardTitle = i18n.translate( + 'sharedUXComponents.noDataPage.elasticAgentCard.title', + { + defaultMessage: 'Add Elastic Agent', + } +); const elasticAgentCardDescription = i18n.translate( - 'sharedUX.noDataPage.elasticAgentCard.description', + 'sharedUXComponents.noDataPage.elasticAgentCard.description', { defaultMessage: `Use Elastic Agent for a simple, unified way to collect data from your machines.`, } diff --git a/src/plugins/shared_ux/public/components/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 similarity index 92% rename from src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/elastic_agent_card.stories.tsx rename to packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.stories.tsx index ceeb66cbd8cdd..3be77ad8d6dde 100644 --- a/src/plugins/shared_ux/public/components/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 @@ -7,11 +7,12 @@ */ import React from 'react'; +import { applicationServiceFactory } from '@kbn/shared-ux-storybook'; + import { ElasticAgentCardComponent, ElasticAgentCardComponentProps, } from './elastic_agent_card.component'; -import { applicationServiceFactory } from '../../../../services/storybook/application'; export default { title: 'Elastic Agent Data Card', diff --git a/src/plugins/shared_ux/public/components/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 similarity index 87% rename from src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/elastic_agent_card.test.tsx rename to packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.test.tsx index fc9e72a011241..87196e041b2ab 100644 --- a/src/plugins/shared_ux/public/components/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 @@ -8,21 +8,24 @@ import { ReactWrapper } from 'enzyme'; import React from 'react'; -import { ElasticAgentCard } from './elastic_agent_card'; - -import { servicesFactory } from '../../../../services/mocks'; -import { ServicesProvider, SharedUXServices } from '../../../../services'; 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 services: SharedUxServices; let mount: (element: JSX.Element) => ReactWrapper; beforeEach(() => { - services = servicesFactory(); + services = mockServicesFactory(); mount = (element: JSX.Element) => - mountWithIntl({element}); + mountWithIntl({element}); }); afterEach(() => { diff --git a/src/plugins/shared_ux/public/components/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 similarity index 93% rename from src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/elastic_agent_card.tsx rename to packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.tsx index f99c4ec9196f5..d917514a96ccc 100644 --- a/src/plugins/shared_ux/public/components/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 @@ -7,8 +7,9 @@ */ import React from 'react'; +import { useApplication, useHttp, usePermissions } from '@kbn/shared-ux-services'; + import { ElasticAgentCardProps } from './types'; -import { useApplication, useHttp, usePermissions } from '../../../../services'; import { ElasticAgentCardComponent } from './elastic_agent_card.component'; export const ElasticAgentCard = (props: ElasticAgentCardProps) => { diff --git a/src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/index.ts b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/index.ts similarity index 100% rename from src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/index.ts rename to packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/index.ts diff --git a/src/plugins/shared_ux/public/components/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 similarity index 100% rename from src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/no_data_card.stories.tsx rename to packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.stories.tsx diff --git a/src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/no_data_card.styles.ts b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.styles.ts similarity index 100% rename from src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/no_data_card.styles.ts rename to packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.styles.ts diff --git a/src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/no_data_card.test.tsx b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.test.tsx similarity index 100% rename from src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/no_data_card.test.tsx rename to packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.test.tsx diff --git a/src/plugins/shared_ux/public/components/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 similarity index 82% rename from src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/no_data_card.tsx rename to packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.tsx index 2ea601757fbf7..4cba71bc09851 100644 --- a/src/plugins/shared_ux/public/components/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 @@ -9,16 +9,23 @@ import { i18n } from '@kbn/i18n'; import React, { FunctionComponent } from 'react'; import { EuiButton, EuiCard } from '@elastic/eui'; + import type { NoDataCardProps } from './types'; import { NoDataCardStyles } from './no_data_card.styles'; -const recommendedLabel = i18n.translate('sharedUX.pageTemplate.noDataPage.recommendedLabel', { - defaultMessage: 'Recommended', -}); +const recommendedLabel = i18n.translate( + 'sharedUXComponents.pageTemplate.noDataPage.recommendedLabel', + { + defaultMessage: 'Recommended', + } +); -const defaultDescription = i18n.translate('sharedUX.pageTemplate.noDataCard.description', { - defaultMessage: 'Proceed without collecting data', -}); +const defaultDescription = i18n.translate( + 'sharedUXComponents.pageTemplate.noDataCard.description', + { + defaultMessage: `Proceed without collecting data`, + } +); export const NoDataCard: FunctionComponent = ({ recommended, diff --git a/src/plugins/shared_ux/public/components/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 similarity index 100% rename from src/plugins/shared_ux/public/components/page_template/no_data_page/no_data_card/types.ts rename to packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/types.ts diff --git a/src/plugins/shared_ux/public/components/redirect_app_links/click_handler.test.ts b/packages/kbn-shared-ux-components/src/redirect_app_links/click_handler.test.ts similarity index 97% rename from src/plugins/shared_ux/public/components/redirect_app_links/click_handler.test.ts rename to packages/kbn-shared-ux-components/src/redirect_app_links/click_handler.test.ts index 1569203c394df..dd26443eed171 100644 --- a/src/plugins/shared_ux/public/components/redirect_app_links/click_handler.test.ts +++ b/packages/kbn-shared-ux-components/src/redirect_app_links/click_handler.test.ts @@ -7,7 +7,6 @@ */ import { MouseEvent } from 'react'; -import { ApplicationStart } from 'src/core/public'; import { createNavigateToUrlClickHandler } from './click_handler'; const createLink = ({ @@ -42,9 +41,11 @@ const createEvent = ({ } as unknown as MouseEvent; }; +type NavigateToURLFn = (url: string) => Promise; + describe('createNavigateToUrlClickHandler', () => { let container: HTMLElement; - let navigateToUrl: jest.MockedFunction; + let navigateToUrl: jest.MockedFunction; const createHandler = () => createNavigateToUrlClickHandler({ diff --git a/src/plugins/shared_ux/public/components/redirect_app_links/click_handler.ts b/packages/kbn-shared-ux-components/src/redirect_app_links/click_handler.ts similarity index 87% rename from src/plugins/shared_ux/public/components/redirect_app_links/click_handler.ts rename to packages/kbn-shared-ux-components/src/redirect_app_links/click_handler.ts index 89b057ffd0eaa..db2990726dc93 100644 --- a/src/plugins/shared_ux/public/components/redirect_app_links/click_handler.ts +++ b/packages/kbn-shared-ux-components/src/redirect_app_links/click_handler.ts @@ -7,11 +7,10 @@ */ import React from 'react'; -import { ApplicationStart } from 'src/core/public'; -import { getClosestLink, hasActiveModifierKey } from '../utility/utils'; +import { getClosestLink, hasActiveModifierKey } from '@kbn/shared-ux-utility'; interface CreateCrossAppClickHandlerOptions { - navigateToUrl: ApplicationStart['navigateToUrl']; + navigateToUrl(url: string): Promise; container?: HTMLElement; } diff --git a/src/plugins/shared_ux/public/components/redirect_app_links/index.ts b/packages/kbn-shared-ux-components/src/redirect_app_links/index.ts similarity index 100% rename from src/plugins/shared_ux/public/components/redirect_app_links/index.ts rename to packages/kbn-shared-ux-components/src/redirect_app_links/index.ts diff --git a/src/plugins/shared_ux/public/components/redirect_app_links/redirect_app_links.mdx b/packages/kbn-shared-ux-components/src/redirect_app_links/redirect_app_links.mdx similarity index 100% rename from src/plugins/shared_ux/public/components/redirect_app_links/redirect_app_links.mdx rename to packages/kbn-shared-ux-components/src/redirect_app_links/redirect_app_links.mdx diff --git a/src/plugins/shared_ux/public/components/redirect_app_links/redirect_app_links.stories.tsx b/packages/kbn-shared-ux-components/src/redirect_app_links/redirect_app_links.stories.tsx similarity index 100% rename from src/plugins/shared_ux/public/components/redirect_app_links/redirect_app_links.stories.tsx rename to packages/kbn-shared-ux-components/src/redirect_app_links/redirect_app_links.stories.tsx diff --git a/src/plugins/shared_ux/public/components/redirect_app_links/redirect_app_links.test.tsx b/packages/kbn-shared-ux-components/src/redirect_app_links/redirect_app_links.test.tsx similarity index 93% rename from src/plugins/shared_ux/public/components/redirect_app_links/redirect_app_links.test.tsx rename to packages/kbn-shared-ux-components/src/redirect_app_links/redirect_app_links.test.tsx index d2cf5aa664cc6..d36bace70b7c8 100644 --- a/src/plugins/shared_ux/public/components/redirect_app_links/redirect_app_links.test.tsx +++ b/packages/kbn-shared-ux-components/src/redirect_app_links/redirect_app_links.test.tsx @@ -8,18 +8,30 @@ import React, { MouseEvent } from 'react'; import { mount } from 'enzyme'; -import { applicationServiceMock } from '../../../../../core/public/mocks'; -import { RedirectAppLinks } from './redirect_app_links'; import { BehaviorSubject } from 'rxjs'; +import { RedirectAppLinks } from './redirect_app_links'; + +export type UnmountCallback = () => void; +export type MountPoint = (element: T) => UnmountCallback; + +const createServiceMock = () => { + const currentAppId$ = new BehaviorSubject('currentApp'); + + return { + currentAppId$: currentAppId$.asObservable(), + navigateToApp: jest.fn(), + navigateToUrl: jest.fn(), + }; +}; + /* eslint-disable jsx-a11y/click-events-have-key-events */ describe('RedirectAppLinks', () => { - let application: ReturnType; + let application = createServiceMock(); beforeEach(() => { - application = applicationServiceMock.createStartContract(); - application.currentAppId$ = new BehaviorSubject('currentApp'); + application = createServiceMock(); }); it('intercept click events on children link elements', () => { diff --git a/src/plugins/shared_ux/public/components/redirect_app_links/redirect_app_links.tsx b/packages/kbn-shared-ux-components/src/redirect_app_links/redirect_app_links.tsx similarity index 76% rename from src/plugins/shared_ux/public/components/redirect_app_links/redirect_app_links.tsx rename to packages/kbn-shared-ux-components/src/redirect_app_links/redirect_app_links.tsx index 5c2d9260639ca..e1d0bd4bed653 100644 --- a/src/plugins/shared_ux/public/components/redirect_app_links/redirect_app_links.tsx +++ b/packages/kbn-shared-ux-components/src/redirect_app_links/redirect_app_links.tsx @@ -6,17 +6,21 @@ * Side Public License, v 1. */ -import React, { FunctionComponent, useRef, useMemo } from 'react'; +import React, { useRef, useMemo } from 'react'; +import type { HTMLAttributes, DetailedHTMLProps, FC } from 'react'; import useObservable from 'react-use/lib/useObservable'; -import { ApplicationStart } from 'src/core/public'; -import { createNavigateToUrlClickHandler } from './click_handler'; +import { Observable } from 'rxjs'; -type Props = React.HTMLAttributes & - Pick; +import { createNavigateToUrlClickHandler } from './click_handler'; -export interface RedirectAppLinksProps extends Props { - className?: string; - 'data-test-subj'?: string; +type DivProps = DetailedHTMLProps, HTMLDivElement>; +/** + * TODO: this interface recreates props from the `ApplicationStart` interface. + * see: https://github.com/elastic/kibana/issues/127695 + */ +export interface RedirectAppLinksProps extends DivProps { + currentAppId$: Observable; + navigateToUrl(url: string): Promise; } /** @@ -36,7 +40,7 @@ export interface RedirectAppLinksProps extends Props { * require to handle the links. A good practice is to consider it as a context provider and to use it * at the root level of an application or of the page that require the feature. */ -export const RedirectAppLinks: FunctionComponent = ({ +export const RedirectAppLinks: FC = ({ navigateToUrl, currentAppId$, children, diff --git a/packages/kbn-shared-ux-components/src/svg.d.ts b/packages/kbn-shared-ux-components/src/svg.d.ts new file mode 100644 index 0000000000000..9169166fe7af9 --- /dev/null +++ b/packages/kbn-shared-ux-components/src/svg.d.ts @@ -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. + */ + +declare module '*.svg' { + const content: string; + // eslint-disable-next-line import/no-default-export + export default content; +} diff --git a/src/plugins/shared_ux/public/components/toolbar/buttons/icon_button_group/__snapshots__/icon_button_group.test.tsx.snap b/packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/__snapshots__/icon_button_group.test.tsx.snap similarity index 98% rename from src/plugins/shared_ux/public/components/toolbar/buttons/icon_button_group/__snapshots__/icon_button_group.test.tsx.snap rename to packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/__snapshots__/icon_button_group.test.tsx.snap index 9e0e13d628702..b49efda2a1cf7 100644 --- a/src/plugins/shared_ux/public/components/toolbar/buttons/icon_button_group/__snapshots__/icon_button_group.test.tsx.snap +++ b/packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/__snapshots__/icon_button_group.test.tsx.snap @@ -16,7 +16,7 @@ exports[` is rendered 1`] = ` border-bottom-right-radius: 6px!important; } - is rendered 1`] = ` } docLinks={ Object { - "dataViewsDocsLink": "dummy link", + "dataViewsDocLink": "dummy link", } } editors={ @@ -212,5 +212,5 @@ exports[` is rendered 1`] = ` - + `; diff --git a/src/plugins/shared_ux/public/components/toolbar/buttons/icon_button_group/icon_button_group.mdx b/packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/icon_button_group.mdx similarity index 100% rename from src/plugins/shared_ux/public/components/toolbar/buttons/icon_button_group/icon_button_group.mdx rename to packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/icon_button_group.mdx diff --git a/src/plugins/shared_ux/public/components/toolbar/buttons/icon_button_group/icon_button_group.stories.tsx b/packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/icon_button_group.stories.tsx similarity index 100% rename from src/plugins/shared_ux/public/components/toolbar/buttons/icon_button_group/icon_button_group.stories.tsx rename to packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/icon_button_group.stories.tsx diff --git a/src/plugins/shared_ux/public/components/toolbar/buttons/icon_button_group/icon_button_group.styles.ts b/packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/icon_button_group.styles.ts similarity index 100% rename from src/plugins/shared_ux/public/components/toolbar/buttons/icon_button_group/icon_button_group.styles.ts rename to packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/icon_button_group.styles.ts diff --git a/src/plugins/shared_ux/public/components/toolbar/buttons/icon_button_group/icon_button_group.test.tsx b/packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/icon_button_group.test.tsx similarity index 77% rename from src/plugins/shared_ux/public/components/toolbar/buttons/icon_button_group/icon_button_group.test.tsx rename to packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/icon_button_group.test.tsx index 751476bb5648c..aefcd59fbd7d5 100644 --- a/src/plugins/shared_ux/public/components/toolbar/buttons/icon_button_group/icon_button_group.test.tsx +++ b/packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/icon_button_group.test.tsx @@ -8,19 +8,22 @@ import React from 'react'; import { mount as enzymeMount, ReactWrapper } from 'enzyme'; +import { + mockServicesFactory, + SharedUxServices, + SharedUxServicesProvider, +} from '@kbn/shared-ux-services'; -import { ServicesProvider, SharedUXServices } from '../../../../services'; -import { servicesFactory } from '../../../../services/mocks'; import { IconButtonGroup } from './icon_button_group'; describe('', () => { - let services: SharedUXServices; + let services: SharedUxServices; let mount: (element: JSX.Element) => ReactWrapper; beforeEach(() => { - services = servicesFactory(); + services = mockServicesFactory(); mount = (element: JSX.Element) => - enzymeMount({element}); + enzymeMount({element}); }); test('is rendered', () => { diff --git a/src/plugins/shared_ux/public/components/toolbar/buttons/icon_button_group/icon_button_group.tsx b/packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/icon_button_group.tsx similarity index 100% rename from src/plugins/shared_ux/public/components/toolbar/buttons/icon_button_group/icon_button_group.tsx rename to packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/icon_button_group.tsx diff --git a/src/plugins/shared_ux/public/components/toolbar/buttons/primary/__snapshots__/primary.test.tsx.snap b/packages/kbn-shared-ux-components/src/toolbar/buttons/primary/__snapshots__/primary.test.tsx.snap similarity index 94% rename from src/plugins/shared_ux/public/components/toolbar/buttons/primary/__snapshots__/primary.test.tsx.snap rename to packages/kbn-shared-ux-components/src/toolbar/buttons/primary/__snapshots__/primary.test.tsx.snap index eecbcee5d99eb..8e447f7a0ee5c 100644 --- a/src/plugins/shared_ux/public/components/toolbar/buttons/primary/__snapshots__/primary.test.tsx.snap +++ b/packages/kbn-shared-ux-components/src/toolbar/buttons/primary/__snapshots__/primary.test.tsx.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[` is rendered 1`] = ` - is rendered 1`] = ` } docLinks={ Object { - "dataViewsDocsLink": "dummy link", + "dataViewsDocLink": "dummy link", } } editors={ @@ -88,5 +88,5 @@ exports[` is rendered 1`] = ` - + `; diff --git a/src/plugins/shared_ux/public/components/toolbar/buttons/primary/primary.mdx b/packages/kbn-shared-ux-components/src/toolbar/buttons/primary/primary.mdx similarity index 100% rename from src/plugins/shared_ux/public/components/toolbar/buttons/primary/primary.mdx rename to packages/kbn-shared-ux-components/src/toolbar/buttons/primary/primary.mdx diff --git a/src/plugins/shared_ux/public/components/toolbar/buttons/primary/primary.stories.tsx b/packages/kbn-shared-ux-components/src/toolbar/buttons/primary/primary.stories.tsx similarity index 100% rename from src/plugins/shared_ux/public/components/toolbar/buttons/primary/primary.stories.tsx rename to packages/kbn-shared-ux-components/src/toolbar/buttons/primary/primary.stories.tsx diff --git a/src/plugins/shared_ux/public/components/toolbar/buttons/primary/primary.test.tsx b/packages/kbn-shared-ux-components/src/toolbar/buttons/primary/primary.test.tsx similarity index 79% rename from src/plugins/shared_ux/public/components/toolbar/buttons/primary/primary.test.tsx rename to packages/kbn-shared-ux-components/src/toolbar/buttons/primary/primary.test.tsx index adcf9e178feaa..e93d537a40ce5 100644 --- a/src/plugins/shared_ux/public/components/toolbar/buttons/primary/primary.test.tsx +++ b/packages/kbn-shared-ux-components/src/toolbar/buttons/primary/primary.test.tsx @@ -8,19 +8,23 @@ import { mount as enzymeMount, ReactWrapper } from 'enzyme'; import React from 'react'; -import { ServicesProvider, SharedUXServices } from '../../../../services'; -import { servicesFactory } from '../../../../services/mocks'; + +import { + SharedUxServicesProvider, + SharedUxServices, + mockServicesFactory, +} from '@kbn/shared-ux-services'; import { ToolbarButton } from './primary'; describe('', () => { - let services: SharedUXServices; + let services: SharedUxServices; let mount: (element: JSX.Element) => ReactWrapper; beforeEach(() => { - services = servicesFactory(); + services = mockServicesFactory(); mount = (element: JSX.Element) => - enzymeMount({element}); + enzymeMount({element}); }); afterEach(() => { diff --git a/src/plugins/shared_ux/public/components/toolbar/buttons/primary/primary.tsx b/packages/kbn-shared-ux-components/src/toolbar/buttons/primary/primary.tsx similarity index 100% rename from src/plugins/shared_ux/public/components/toolbar/buttons/primary/primary.tsx rename to packages/kbn-shared-ux-components/src/toolbar/buttons/primary/primary.tsx diff --git a/src/plugins/shared_ux/public/components/toolbar/index.ts b/packages/kbn-shared-ux-components/src/toolbar/index.ts similarity index 100% rename from src/plugins/shared_ux/public/components/toolbar/index.ts rename to packages/kbn-shared-ux-components/src/toolbar/index.ts diff --git a/packages/kbn-shared-ux-components/tsconfig.json b/packages/kbn-shared-ux-components/tsconfig.json new file mode 100644 index 0000000000000..cca91264519cc --- /dev/null +++ b/packages/kbn-shared-ux-components/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": "src", + "stripInternal": false, + "types": [ + "jest", + "node", + "@emotion/react/types/css-prop" + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/packages/kbn-shared-ux-services/BUILD.bazel b/packages/kbn-shared-ux-services/BUILD.bazel new file mode 100755 index 0000000000000..0345e98cd7123 --- /dev/null +++ b/packages/kbn-shared-ux-services/BUILD.bazel @@ -0,0 +1,126 @@ +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 = "kbn-shared-ux-services" +PKG_REQUIRE_NAME = "@kbn/shared-ux-services" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + "src/**/*.tsx", + ], + 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", +] + +# 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", + "@npm//rxjs", +] + +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, +) + +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/kbn-shared-ux-services/README.mdx b/packages/kbn-shared-ux-services/README.mdx new file mode 100755 index 0000000000000..205c175000fb2 --- /dev/null +++ b/packages/kbn-shared-ux-services/README.mdx @@ -0,0 +1,203 @@ +--- +id: kibSharedUXServices +slug: /kibana-dev-docs/shared-ux/packages/kbn-shared-ux-services +title: Shared UX Services +summary: The `@kbn/shared-ux-services` package provides a thin service abstraction for components and solutions created by the Shared UX team. +date: 2022-03-11 +tags: ['kibana', 'dev', 'sharedUX'] +--- + +## About Shared UX Services + +This package contains a set of services that are used by Shared UX components and solutions. This package serves as a thin abstraction layer between Kibana dependencies and the components in Shared UX that use them. It also allows us to "swap out" different implementations of the interfaces for different environments, (e.g. Storybook, Jest, etc). This decouples the components from what could be complicated or heavily-dependent logic that is difficult to mock. + +## Implementations + +Several implementations of these interfaces exist: + +- `@kbn/shared-ux-services/src/services/stub`: A stub implementation free of dependencies, (and functionality). +- `@kbn/shared-ux-services/src/services/mock`: A Jest mock implementation used in `jest` tests. +- `@kbn/shared-ux-storybook/src/services/`: A Storybook implementation used in Storybook decorators and stories. +- `src/plugins/shared_ux/src/services/`: A Kibana implementation used in Kibana plugins. + +Other implementations could easily be written to support other environments. + +## Architecture + +Lots of components require access to the services provided by other plugins. When we identify a routine that relies on these dependencies, we can write a new method and add it to a namespace, (e.g. `platform`, `user`, etc). These namespaces become interfaces of simple methods stored in `@kbn/shared-ux-services`. From there, we can create implementations for each environment we support. + +Suppose we're creating a new service, `SharedUxFooService`: + +```ts +interface SharedUxFooService { + getFoo(): string; + setBar(bar: string): void; + isBaz(): boolean; +} +``` + +Once defined, we create factories to create those services. + +### Creating a `ServiceFactory` + +A `ServiceFactory` is a simple type that describes 1/ what service is being created, and 2/ what parameters are required to create that service for a given environment. + +### Stub and Mock Factories + +Given the service definition above, we can create a `ServiceFactory` for a stubbed service that gives the bare minimum of functionality: + +```ts +/** + * A factory function for creating a stubbed implementation of `SharedUxFooService`. + */ +export type FooServiceFactory = ServiceFactory; + +/** + * A factory function for creating a stubbed implementation of `SharedUxFooService`. + */ +export const fooServiceFactory: FooServiceFactory = () => ({ + getFoo: () => 'foo', + setBar: () => {}, + isBaz: () => false, +}); +``` + +We can also create a mock for Jest: + +```ts +/** + * A factory function for creating a mock implementation of `SharedUxFooService`. + */ +export type FooServiceFactory = ServiceFactory; + +/** + * A factory function for creating a stubbed implementation of `SharedUxFooService`. + */ +export const fooServiceFactory: FooServiceFactory = () => ({ + getFoo: () => jest.fn(), + setBar: () => jest.fn(), + isBaz: () => jest.fn(), +}); +``` + +### Storybook Factories + +Storybook is where we can begin to take advantage of `Parameters` for a given service. Since stories can use controls to provide parameters, we can create a `ServiceFactory` that uses the `Parameters` generic and returns a `SharedUxFooService` that uses their values. + +```ts +import { action } from '@storybook/addon-actions'; + +interface FooServiceStorybookParameters { + foo: string; + baz: boolean; +} + +/** + * A factory function for creating a Storybook implementation of `SharedUxFooService`. + */ +export type FooServiceFactory = ServiceFactory; + +/** + * A factory function for creating a stubbed implementation of `SharedUxFooService`. + */ +export const fooServiceFactory: FooServiceFactory = ({ foo, baz }) => ({ + getFoo: () => foo, + setBar: () => action('setBar'), + isBaz: () => baz, +}); +``` + +A story can then optionally provide values for those parameters as part of its controls. + +```ts +type Params = Pick; + +export const ComponentStory = ({ foo }: Params) => { + const service = fooServiceFactory({ foo, baz: false }); + + return ( + ; +}; + +PureComponent.argTypes = { + foo: { + options: ['alpha', 'beta', 'gamma', 'delta'], + control: { type: 'radio' }, + }, +}; +``` + +### Kibana Factories + +Using these services in Kibana is a bit more complex, but is still relatively simple. First, we define what dependencies we'll need, (we use this interface in `src/plugins/shared_ux` as it relies on types found only in plugins, where packages cannot use them): + +```ts +/** + * Parameters necessary to create a Kibana-based service, (e.g. during Plugin + * startup or setup). + * + * The `Start` generic refers to the specific Plugin `TPluginsStart`. + */ +export interface KibanaPluginServiceParams { + coreStart: CoreStart; + startPlugins: Start; + appUpdater?: BehaviorSubject; + initContext?: PluginInitializerContext; +} + +/** + * A factory function for creating a Kibana-based service. + * + * The `Service` generic determines the shape of the Service being produced. + * The `Start` generic refers to the specific Plugin `TPluginsStart`. + */ +export type KibanaPluginServiceFactory = ( + params: KibanaPluginServiceParams +) => Service; +``` + +From there, a plugin might have a collection of dependencies on core or other plugins: + +```ts +export interface MyPluginStartDeps { + bar: BarPluginStart; + baz: BazPluginStart; +} +``` + +We'd then use this dependency interface to create a `ServiceFactory` for our service in Kibana: + +```ts +export type FooServiceFactory = KibanaPluginServiceFactory< + SharedUxFooService, + MyPluginStartDeps +>; + +/** + * A factory function for creating a Kibana-based implementation of `SharedUxFooService`. + */ +export const fooServiceFactory: FooServiceFactory = ({ coreStart, startPlugins }) => ({ + getFoo: startPlugins.bar.getSomeOtherFoo, + setBar: startPlugins.baz.setHappyPathBar, + isBaz: () => { + return coreStart.uiSettings.get('someSetting') === 'expectedValue'; + } +}); +``` + +From there, the pattern is the same: invoke the service factory with the required dependencies and provide them to the `SharedUxServicesContext` Provider: + +```ts + +// plugin.tsx +public start(coreStart: CoreStart, startPlugins: SharedUXPluginStartDeps): SharedUXPluginStart { + const service = fooServiceFactory({ coreStart, startPlugins }); + const Context = {children}; + + // ...wrap React content with the context.. +} +``` + +## Use in Kibana plugins + +In order to make consumption of these services easy by Kibana plugins, `src/plugins/shared_ux` provides a pre-wired `SharedUxServicesProvider` component as part of the `start` lifecycle. Plugins can simply make `sharedUX` a dependency and wrap their solution root or any component. See the documentation for `sharedUX` for more details. diff --git a/packages/kbn-shared-ux-services/jest.config.js b/packages/kbn-shared-ux-services/jest.config.js new file mode 100755 index 0000000000000..f1ef008d0f62d --- /dev/null +++ b/packages/kbn-shared-ux-services/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/kbn-shared-ux-services'], +}; diff --git a/packages/kbn-shared-ux-services/package.json b/packages/kbn-shared-ux-services/package.json new file mode 100755 index 0000000000000..7d7d999bf6961 --- /dev/null +++ b/packages/kbn-shared-ux-services/package.json @@ -0,0 +1,8 @@ +{ + "name": "@kbn/shared-ux-services", + "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/kbn-shared-ux-services/src/context.tsx b/packages/kbn-shared-ux-services/src/context.tsx new file mode 100644 index 0000000000000..55d05c57a08fb --- /dev/null +++ b/packages/kbn-shared-ux-services/src/context.tsx @@ -0,0 +1,65 @@ +/* + * 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, createContext, useContext } from 'react'; + +import type { SharedUxServices } from './types'; + +// The React Context used to provide the services to the SharedUX components. +const SharedUxServicesContext = createContext(null); + +/** + * The `React.Context` Provider component for the `SharedUxServices` context. Any + * plugin or environment that consumes SharedUX components needs to wrap their React + * tree with this provider. + * + * Within a plugin, you can use use the Shared UX plugin and retrieve a fully-configured + * context from the `start` contract. + */ +export const SharedUxServicesProvider: FC = ({ children, ...services }) => ( + {children} +); + +/** + * React hook for accessing pre-wired `SharedUxServices`. + */ +export function useSharedUxServices() { + const context = useContext(SharedUxServicesContext); + + if (!context) { + throw new Error( + 'SharedUxServicesContext missing. Ensure your component or React root is wrapped with SharedUxServicesProvider.' + ); + } + + return context; +} + +/** + * React hook for accessing the pre-wired `SharedUxPlatformService`. + */ +export const usePlatformService = () => useSharedUxServices().platform; + +/** + * React hook for accessing the pre-wired `SharedUxPermissionsService`. + */ +export const usePermissions = () => useSharedUxServices().permissions; + +/** + * React hook for accessing the pre-wired `SharedUxEditorsService`. + */ +export const useEditors = () => useSharedUxServices().editors; + +/** + * React hook for accessing the pre-wired `SharedUxDocLinksService`. + */ +export const useDocLinks = () => useSharedUxServices().docLinks; + +export const useHttp = () => useSharedUxServices().http; + +export const useApplication = () => useSharedUxServices().application; diff --git a/packages/kbn-shared-ux-services/src/index.ts b/packages/kbn-shared-ux-services/src/index.ts new file mode 100755 index 0000000000000..d9ea2c670c9c5 --- /dev/null +++ b/packages/kbn-shared-ux-services/src/index.ts @@ -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. + */ + +export type { ServiceFactory, SharedUxServices, SharedUxServicesContext } from './types'; +export type { + SharedUxApplicationService, + SharedUxDocLinksService, + SharedUxEditorsService, + SharedUxHttpService, + SharedUxPlatformService, + SharedUxUserPermissionsService, +} from './services'; + +export { + SharedUxServicesProvider, + useApplication, + useDocLinks, + useEditors, + useHttp, + usePermissions, + usePlatformService, + useSharedUxServices, +} from './context'; + +export { + mockServiceFactories, + mockServicesFactory, + stubServiceFactories, + stubServicesFactory, +} from './services'; diff --git a/packages/kbn-shared-ux-services/src/services/application.ts b/packages/kbn-shared-ux-services/src/services/application.ts new file mode 100644 index 0000000000000..be2ca2f2730cb --- /dev/null +++ b/packages/kbn-shared-ux-services/src/services/application.ts @@ -0,0 +1,14 @@ +/* + * 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 { Observable } from 'rxjs'; + +export interface SharedUxApplicationService { + navigateToUrl: (url: string) => Promise; + currentAppId$: Observable; +} diff --git a/packages/kbn-shared-ux-services/src/services/doc_links.ts b/packages/kbn-shared-ux-services/src/services/doc_links.ts new file mode 100644 index 0000000000000..3b8eb4748d76f --- /dev/null +++ b/packages/kbn-shared-ux-services/src/services/doc_links.ts @@ -0,0 +1,15 @@ +/* + * 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. + */ + +/** + * A service providing links to documentation about various features in Kibana. + */ +export interface SharedUxDocLinksService { + /** A link to information about Data Views in Kibana */ + dataViewsDocLink: string; +} diff --git a/packages/kbn-shared-ux-services/src/services/editors.ts b/packages/kbn-shared-ux-services/src/services/editors.ts new file mode 100644 index 0000000000000..4dc5b7d9bc269 --- /dev/null +++ b/packages/kbn-shared-ux-services/src/services/editors.ts @@ -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. + */ + +/** + * 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 our service and components. + * + * @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 service providing methods to invoke and interact with various editors provided + * in Kibana. + */ +export interface SharedUxEditorsService { + /** A method to open the Data View Editor flow. */ + openDataViewEditor: (options: DataViewEditorOptions) => () => void; +} diff --git a/packages/kbn-shared-ux-services/src/services/http.ts b/packages/kbn-shared-ux-services/src/services/http.ts new file mode 100644 index 0000000000000..024222092b7b1 --- /dev/null +++ b/packages/kbn-shared-ux-services/src/services/http.ts @@ -0,0 +1,11 @@ +/* + * 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 interface SharedUxHttpService { + addBasePath: (url: string) => string; +} diff --git a/packages/kbn-shared-ux-services/src/services/index.ts b/packages/kbn-shared-ux-services/src/services/index.ts new file mode 100644 index 0000000000000..485264353feb2 --- /dev/null +++ b/packages/kbn-shared-ux-services/src/services/index.ts @@ -0,0 +1,17 @@ +/* + * 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 type { SharedUxApplicationService } from './application'; +export type { SharedUxDocLinksService } from './doc_links'; +export type { SharedUxEditorsService } from './editors'; +export type { SharedUxHttpService } from './http'; +export type { SharedUxUserPermissionsService } from './permissions'; +export type { SharedUxPlatformService } from './platform'; + +export { mockServicesFactory, mockServiceFactories } from './mock'; +export { stubServicesFactory, stubServiceFactories } from './stub'; diff --git a/src/plugins/shared_ux/public/services/mocks/application.mock.ts b/packages/kbn-shared-ux-services/src/services/mock/application.mock.ts similarity index 76% rename from src/plugins/shared_ux/public/services/mocks/application.mock.ts rename to packages/kbn-shared-ux-services/src/services/mock/application.mock.ts index c2010956401e8..abb68a1edb642 100644 --- a/src/plugins/shared_ux/public/services/mocks/application.mock.ts +++ b/packages/kbn-shared-ux-services/src/services/mock/application.mock.ts @@ -6,11 +6,11 @@ * Side Public License, v 1. */ -import { PluginServiceFactory } from '../types'; -import { SharedUXApplicationService } from '../application'; import { Observable } from 'rxjs'; +import { ServiceFactory } from '../../types'; +import { SharedUxApplicationService } from '../application'; -export type MockApplicationServiceFactory = PluginServiceFactory; +export type MockApplicationServiceFactory = ServiceFactory; /** * A factory function for creating a Jest-based implementation of `SharedUXApplicationService`. diff --git a/src/plugins/shared_ux/public/services/mocks/doc_links.mock.ts b/packages/kbn-shared-ux-services/src/services/mock/doc_links.mock.ts similarity index 59% rename from src/plugins/shared_ux/public/services/mocks/doc_links.mock.ts rename to packages/kbn-shared-ux-services/src/services/mock/doc_links.mock.ts index 28cfa14c50d28..378ead63fbc9f 100644 --- a/src/plugins/shared_ux/public/services/mocks/doc_links.mock.ts +++ b/packages/kbn-shared-ux-services/src/services/mock/doc_links.mock.ts @@ -6,14 +6,17 @@ * Side Public License, v 1. */ -import { PluginServiceFactory } from '../types'; -import { SharedUXDocLinksService } from '../doc_links'; +import type { ServiceFactory } from '../../types'; +import type { SharedUxDocLinksService } from '../doc_links'; -export type MockDockLinksServiceFactory = PluginServiceFactory; +/** + * A factory function for creating a Jest implementation of `SharedUxDocLinksService`. + */ +export type MockDockLinksServiceFactory = ServiceFactory; /** - * A factory function for creating a Jest-based implementation of `SharedUXDocLinksService`. + * A factory function for creating a Jest-based implementation of `SharedUxDocLinksService`. */ export const docLinksServiceFactory: MockDockLinksServiceFactory = () => ({ - dataViewsDocsLink: 'dummy link', + dataViewsDocLink: 'dummy link', }); diff --git a/src/plugins/shared_ux/public/services/mocks/editors.mock.ts b/packages/kbn-shared-ux-services/src/services/mock/editors.mock.ts similarity index 62% rename from src/plugins/shared_ux/public/services/mocks/editors.mock.ts rename to packages/kbn-shared-ux-services/src/services/mock/editors.mock.ts index 28a89d5326d62..80742f15d93cd 100644 --- a/src/plugins/shared_ux/public/services/mocks/editors.mock.ts +++ b/packages/kbn-shared-ux-services/src/services/mock/editors.mock.ts @@ -6,13 +6,16 @@ * Side Public License, v 1. */ -import { PluginServiceFactory } from '../types'; -import { SharedUXEditorsService } from '../editors'; +import type { ServiceFactory } from '../../types'; +import type { SharedUxEditorsService } from '../editors'; -export type MockEditorsServiceFactory = PluginServiceFactory; +/** + * A factory function for creating a Jest-based implementation of `SharedUxEditorsService`. + */ +export type MockEditorsServiceFactory = ServiceFactory; /** - * A factory function for creating a Jest-based implementation of `SharedUXEditorsService`. + * A factory function for creating a Jest-based implementation of `SharedUxEditorsService`. */ export const editorsServiceFactory: MockEditorsServiceFactory = () => ({ openDataViewEditor: jest.fn(), diff --git a/src/plugins/shared_ux/public/services/mocks/http.mock.ts b/packages/kbn-shared-ux-services/src/services/mock/http.mock.ts similarity index 77% rename from src/plugins/shared_ux/public/services/mocks/http.mock.ts rename to packages/kbn-shared-ux-services/src/services/mock/http.mock.ts index 1751f2b77efc1..0ef07526e5116 100644 --- a/src/plugins/shared_ux/public/services/mocks/http.mock.ts +++ b/packages/kbn-shared-ux-services/src/services/mock/http.mock.ts @@ -6,10 +6,10 @@ * Side Public License, v 1. */ -import { PluginServiceFactory } from '../types'; -import { SharedUXHttpService } from '../http'; +import { ServiceFactory } from '../../types'; +import { SharedUxHttpService } from '../http'; -export type MockHttpServiceFactory = PluginServiceFactory; +export type MockHttpServiceFactory = ServiceFactory; /** * A factory function for creating a Jest-based implementation of `SharedUXHttpService`. diff --git a/src/plugins/shared_ux/public/services/mocks/index.ts b/packages/kbn-shared-ux-services/src/services/mock/index.ts similarity index 51% rename from src/plugins/shared_ux/public/services/mocks/index.ts rename to packages/kbn-shared-ux-services/src/services/mock/index.ts index 8fb4372295d76..2fc049a84aeb4 100644 --- a/src/plugins/shared_ux/public/services/mocks/index.ts +++ b/packages/kbn-shared-ux-services/src/services/mock/index.ts @@ -5,27 +5,50 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { docLinksServiceFactory } from './doc_links.mock'; -export type { MockPlatformServiceFactory } from './platform.mock'; -export { platformServiceFactory } from './platform.mock'; +import type { SharedUxServices, ServiceFactory } from '../../types'; -import type { SharedUXServices } from '../.'; -import { PluginServiceFactory } from '../types'; -import { platformServiceFactory } from './platform.mock'; -import { userPermissionsServiceFactory } from './permissions.mock'; +import { applicationServiceFactory } from './application.mock'; +import { docLinksServiceFactory } from './doc_links.mock'; import { editorsServiceFactory } from './editors.mock'; import { httpServiceFactory } from './http.mock'; -import { applicationServiceFactory } from './application.mock'; +import { userPermissionsServiceFactory } from './permissions.mock'; +import { platformServiceFactory } from './platform.mock'; + +export type { MockApplicationServiceFactory } from './application.mock'; +export type { MockDockLinksServiceFactory } from './doc_links.mock'; +export type { MockEditorsServiceFactory } from './editors.mock'; +export type { MockHttpServiceFactory } from './http.mock'; +export type { MockUserPermissionsServiceFactory } from './permissions.mock'; +export type { MockPlatformServiceFactory } from './platform.mock'; + +export { applicationServiceFactory } from './application.mock'; +export { docLinksServiceFactory } from './doc_links.mock'; +export { editorsServiceFactory } from './editors.mock'; +export { httpServiceFactory } from './http.mock'; +export { userPermissionsServiceFactory } from './permissions.mock'; +export { platformServiceFactory } from './platform.mock'; /** - * A factory function for creating a Jest-based implementation of `SharedUXServices`. + * A factory function for creating a Jest-based implementation of `SharedUxServices`. */ -export const servicesFactory: PluginServiceFactory = () => ({ - platform: platformServiceFactory(), - permissions: userPermissionsServiceFactory(), - editors: editorsServiceFactory(), +export const mockServicesFactory: ServiceFactory = () => ({ + application: applicationServiceFactory(), docLinks: docLinksServiceFactory(), + editors: editorsServiceFactory(), http: httpServiceFactory(), - application: applicationServiceFactory(), + permissions: userPermissionsServiceFactory(), + platform: platformServiceFactory(), }); + +/** + * A collection of mock Service Factories. + */ +export const mockServiceFactories = { + applicationServiceFactory, + docLinksServiceFactory, + editorsServiceFactory, + httpServiceFactory, + platformServiceFactory, + userPermissionsServiceFactory, +}; diff --git a/src/plugins/shared_ux/public/services/mocks/permissions.mock.ts b/packages/kbn-shared-ux-services/src/services/mock/permissions.mock.ts similarity index 61% rename from src/plugins/shared_ux/public/services/mocks/permissions.mock.ts rename to packages/kbn-shared-ux-services/src/services/mock/permissions.mock.ts index 4884d5071ec43..3fb5e78a5b839 100644 --- a/src/plugins/shared_ux/public/services/mocks/permissions.mock.ts +++ b/packages/kbn-shared-ux-services/src/services/mock/permissions.mock.ts @@ -6,14 +6,16 @@ * Side Public License, v 1. */ -import { PluginServiceFactory } from '../types'; -import { SharedUXUserPermissionsService } from '../permissions'; +import type { ServiceFactory } from '../../types'; +import type { SharedUxUserPermissionsService } from '../permissions'; -export type MockUserPermissionsServiceFactory = - PluginServiceFactory; +/** + * A factory function for creating a Jest-based implementation of `SharedUxUserPermissionsService`. + */ +export type MockUserPermissionsServiceFactory = ServiceFactory; /** - * A factory function for creating a Jest-based implementation of `SharedUXUserPermissionsService`. + * A factory function for creating a Jest-based implementation of `SharedUxUserPermissionsService`. */ export const userPermissionsServiceFactory: MockUserPermissionsServiceFactory = () => ({ canCreateNewDataView: true, diff --git a/src/plugins/shared_ux/public/services/mocks/platform.mock.ts b/packages/kbn-shared-ux-services/src/services/mock/platform.mock.ts similarity index 70% rename from src/plugins/shared_ux/public/services/mocks/platform.mock.ts rename to packages/kbn-shared-ux-services/src/services/mock/platform.mock.ts index c36d63cfcacbe..8e6ec205d2856 100644 --- a/src/plugins/shared_ux/public/services/mocks/platform.mock.ts +++ b/packages/kbn-shared-ux-services/src/services/mock/platform.mock.ts @@ -6,16 +6,16 @@ * Side Public License, v 1. */ -import type { PluginServiceFactory } from '../types'; -import type { SharedUXPlatformService } from '../platform'; +import type { ServiceFactory } from '../../types'; +import type { SharedUxPlatformService } from '../platform'; /** - * A factory function for creating a Jest-based implementation of `SharedUXPlatformService`. + * A factory function for creating a Jest-based implementation of `SharedUxPlatformService`. */ -export type MockPlatformServiceFactory = PluginServiceFactory; +export type MockPlatformServiceFactory = ServiceFactory; /** - * A factory function for creating a Jest-based implementation of `SharedUXPlatformService`. + * A factory function for creating a Jest-based implementation of `SharedUxPlatformService`. */ export const platformServiceFactory: MockPlatformServiceFactory = () => ({ setIsFullscreen: jest.fn(), diff --git a/packages/kbn-shared-ux-services/src/services/permissions.ts b/packages/kbn-shared-ux-services/src/services/permissions.ts new file mode 100644 index 0000000000000..d6fcabd8ccedf --- /dev/null +++ b/packages/kbn-shared-ux-services/src/services/permissions.ts @@ -0,0 +1,16 @@ +/* + * 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. + */ + +/** + * A service providing permissions information, typically for the current user. + */ +export interface SharedUxUserPermissionsService { + /** True if the user has permission to create a new Data View, false otherwise. */ + canCreateNewDataView: boolean; + canAccessFleet: boolean; +} diff --git a/packages/kbn-shared-ux-services/src/services/platform.ts b/packages/kbn-shared-ux-services/src/services/platform.ts new file mode 100644 index 0000000000000..83148abac8643 --- /dev/null +++ b/packages/kbn-shared-ux-services/src/services/platform.ts @@ -0,0 +1,24 @@ +/* + * 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. + */ + +/** + * A service providing methods to interact with the platform in which this code is + * running, (almost always Kibana). + * + * Rather than provide the entire `CoreStart` contract to components, we provide simplified + * abstractions around a use case specific to Shared UX. This way, we know exactly how the + * `CoreStart` and other plugins are used. This makes mocking and refactoring easier when + * upstream dependencies change. + */ +export interface SharedUxPlatformService { + /** + * Sets the fullscreen state of the chrome. + * @param isFullscreen True if the chrome should be fullscreen, false otherwise. + */ + setIsFullscreen: (isFullscreen: boolean) => void; +} diff --git a/src/plugins/shared_ux/public/services/stub/application.ts b/packages/kbn-shared-ux-services/src/services/stub/application.ts similarity index 80% rename from src/plugins/shared_ux/public/services/stub/application.ts rename to packages/kbn-shared-ux-services/src/services/stub/application.ts index 25ad680a48073..72c1f3db30089 100644 --- a/src/plugins/shared_ux/public/services/stub/application.ts +++ b/packages/kbn-shared-ux-services/src/services/stub/application.ts @@ -7,10 +7,10 @@ */ import { Observable } from 'rxjs'; -import { PluginServiceFactory } from '../types'; -import { SharedUXApplicationService } from '../application'; +import { ServiceFactory } from '../../types'; +import { SharedUxApplicationService } from '../application'; -export type ApplicationServiceFactory = PluginServiceFactory; +export type ApplicationServiceFactory = ServiceFactory; /** * A factory function for creating for creating a simple stubbed implementation of `SharedUXApplicationService`. diff --git a/src/plugins/shared_ux/public/services/stub/doc_links.ts b/packages/kbn-shared-ux-services/src/services/stub/doc_links.ts similarity index 52% rename from src/plugins/shared_ux/public/services/stub/doc_links.ts rename to packages/kbn-shared-ux-services/src/services/stub/doc_links.ts index 424a24c578539..6d22eed944521 100644 --- a/src/plugins/shared_ux/public/services/stub/doc_links.ts +++ b/packages/kbn-shared-ux-services/src/services/stub/doc_links.ts @@ -6,14 +6,17 @@ * Side Public License, v 1. */ -import { PluginServiceFactory } from '../types'; -import { SharedUXDocLinksService } from '../doc_links'; +import type { ServiceFactory } from '../../types'; +import type { SharedUxDocLinksService } from '../doc_links'; -export type DockLinksServiceFactory = PluginServiceFactory; +/** + * A factory function for creating a stubbed implementation of `SharedUxDocLinksService`. + */ +export type DockLinksServiceFactory = ServiceFactory; /** - * A factory function for creating a Jest-based implementation of `SharedUXDocLinksService`. + * A factory function for creating a stubbed implementation of `SharedUxDocLinksService`. */ export const docLinksServiceFactory: DockLinksServiceFactory = () => ({ - dataViewsDocsLink: 'docs', + dataViewsDocLink: 'docs', }); diff --git a/src/plugins/shared_ux/public/services/stub/editors.ts b/packages/kbn-shared-ux-services/src/services/stub/editors.ts similarity index 71% rename from src/plugins/shared_ux/public/services/stub/editors.ts rename to packages/kbn-shared-ux-services/src/services/stub/editors.ts index 03fea5e6c98b5..545539d873941 100644 --- a/src/plugins/shared_ux/public/services/stub/editors.ts +++ b/packages/kbn-shared-ux-services/src/services/stub/editors.ts @@ -6,16 +6,16 @@ * Side Public License, v 1. */ -import { PluginServiceFactory } from '../types'; -import { SharedUXEditorsService } from '../editors'; +import type { ServiceFactory } from '../../types'; +import type { SharedUxEditorsService } from '../editors'; /** - * A factory function for creating a simple stubbed implementation of `SharedUXEditorsService`. + * A factory function for creating a simple stubbed implementation of `SharedUxEditorsService`. */ -export type EditorsServiceFactory = PluginServiceFactory; +export type EditorsServiceFactory = ServiceFactory; /** - * A factory function for creating a simple stubbed implementation of `SharedUXEditorsService`. + * A factory function for creating a simple stubbed implementation of `SharedUxEditorsService`. */ export const editorsServiceFactory: EditorsServiceFactory = () => ({ openDataViewEditor: () => () => {}, diff --git a/src/plugins/shared_ux/public/services/stub/http.ts b/packages/kbn-shared-ux-services/src/services/stub/http.ts similarity index 79% rename from src/plugins/shared_ux/public/services/stub/http.ts rename to packages/kbn-shared-ux-services/src/services/stub/http.ts index 4fb101d4e85f6..08dae62ecdb7f 100644 --- a/src/plugins/shared_ux/public/services/stub/http.ts +++ b/packages/kbn-shared-ux-services/src/services/stub/http.ts @@ -6,13 +6,13 @@ * Side Public License, v 1. */ -import { PluginServiceFactory } from '../types'; -import { SharedUXHttpService } from '../http'; +import { ServiceFactory } from '../../types'; +import { SharedUxHttpService } from '../http'; /** * A factory function for creating a simple stubbed implementation of `SharedUXHttpService`. */ -export type HttpServiceFactory = PluginServiceFactory; +export type HttpServiceFactory = ServiceFactory; /** * A factory function for creating a simple stubbed implementation of `SharedUXHttpService`. diff --git a/src/plugins/shared_ux/public/services/stub/index.ts b/packages/kbn-shared-ux-services/src/services/stub/index.ts similarity index 65% rename from src/plugins/shared_ux/public/services/stub/index.ts rename to packages/kbn-shared-ux-services/src/services/stub/index.ts index 0a8a0b7bd3daf..10323b7db8762 100644 --- a/src/plugins/shared_ux/public/services/stub/index.ts +++ b/packages/kbn-shared-ux-services/src/services/stub/index.ts @@ -6,23 +6,35 @@ * Side Public License, v 1. */ -import type { SharedUXServices } from '../.'; -import { PluginServiceFactory } from '../types'; -import { platformServiceFactory } from './platform'; -import { userPermissionsServiceFactory } from './permissions'; -import { editorsServiceFactory } from './editors'; +import type { SharedUxServices, ServiceFactory } from '../../types'; + +import { applicationServiceFactory } from './application'; import { docLinksServiceFactory } from './doc_links'; +import { editorsServiceFactory } from './editors'; import { httpServiceFactory } from './http'; -import { applicationServiceFactory } from './application'; +import { platformServiceFactory } from './platform'; +import { userPermissionsServiceFactory } from './permissions'; /** - * A factory function for creating a simple stubbed implemetation of `SharedUXServices`. + * A factory function for creating simple stubbed implementations of all `SharedUxServices`. */ -export const servicesFactory: PluginServiceFactory = () => ({ - platform: platformServiceFactory(), - permissions: userPermissionsServiceFactory(), - editors: editorsServiceFactory(), +export const stubServicesFactory: ServiceFactory = () => ({ + application: applicationServiceFactory(), docLinks: docLinksServiceFactory(), + editors: editorsServiceFactory(), http: httpServiceFactory(), - application: applicationServiceFactory(), + permissions: userPermissionsServiceFactory(), + platform: platformServiceFactory(), }); + +/** + * A collection of stubbed service factories. + */ +export const stubServiceFactories = { + applicationServiceFactory, + docLinksServiceFactory, + editorsServiceFactory, + httpServiceFactory, + platformServiceFactory, + userPermissionsServiceFactory, +}; diff --git a/src/plugins/shared_ux/public/services/stub/permissions.ts b/packages/kbn-shared-ux-services/src/services/stub/permissions.ts similarity index 68% rename from src/plugins/shared_ux/public/services/stub/permissions.ts rename to packages/kbn-shared-ux-services/src/services/stub/permissions.ts index 2b9e9f4a8f409..e5588f818f82a 100644 --- a/src/plugins/shared_ux/public/services/stub/permissions.ts +++ b/packages/kbn-shared-ux-services/src/services/stub/permissions.ts @@ -6,16 +6,16 @@ * Side Public License, v 1. */ -import { PluginServiceFactory } from '../types'; -import { SharedUXUserPermissionsService } from '../permissions'; +import type { ServiceFactory } from '../../types'; +import type { SharedUxUserPermissionsService } from '../permissions'; /** - * A factory function for creating a simple stubbed implementation of `SharedUXUserPermissionsService`. + * A factory function for creating a simple stubbed implementation of `SharedUxUserPermissionsService`. */ -export type UserPermissionsServiceFactory = PluginServiceFactory; +export type UserPermissionsServiceFactory = ServiceFactory; /** - * A factory function for creating a simple stubbed implementation of `SharedUXUserPermissionsService`. + * A factory function for creating a simple stubbed implementation of `SharedUxUserPermissionsService`. */ export const userPermissionsServiceFactory: UserPermissionsServiceFactory = () => ({ canCreateNewDataView: true, diff --git a/src/plugins/shared_ux/public/services/stub/platform.ts b/packages/kbn-shared-ux-services/src/services/stub/platform.ts similarity index 70% rename from src/plugins/shared_ux/public/services/stub/platform.ts rename to packages/kbn-shared-ux-services/src/services/stub/platform.ts index 90fa8edb3e06e..2e31238347307 100644 --- a/src/plugins/shared_ux/public/services/stub/platform.ts +++ b/packages/kbn-shared-ux-services/src/services/stub/platform.ts @@ -6,16 +6,16 @@ * Side Public License, v 1. */ -import { PluginServiceFactory } from '../types'; -import { SharedUXPlatformService } from '../platform'; +import type { ServiceFactory } from '../../types'; +import type { SharedUxPlatformService } from '../platform'; /** - * A factory function for creating a simple stubbed implementation of `SharedUXPlatformService`. + * A factory function for creating a simple stubbed implementation of `SharedUxPlatformService`. */ -export type PlatformServiceFactory = PluginServiceFactory; +export type PlatformServiceFactory = ServiceFactory; /** - * A factory function for creating a simple stubbed implementation of `SharedUXPlatformService`. + * A factory function for creating a simple stubbed implementation of `SharedUxPlatformService`. */ export const platformServiceFactory: PlatformServiceFactory = () => ({ setIsFullscreen: (_isFullscreen) => {}, diff --git a/packages/kbn-shared-ux-services/src/types.ts b/packages/kbn-shared-ux-services/src/types.ts new file mode 100755 index 0000000000000..2bfbafb880e80 --- /dev/null +++ b/packages/kbn-shared-ux-services/src/types.ts @@ -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 { FC } from 'react'; + +import { + SharedUxApplicationService, + SharedUxDocLinksService, + SharedUxEditorsService, + SharedUxHttpService, + SharedUxPlatformService, + SharedUxUserPermissionsService, +} from './services'; + +/** + * A collection of services utilized by SharedUX. This serves as a thin + * abstraction layer between services provided by Kibana and other plugins + * while allowing this plugin to be developed independently of those contracts. + * + * It also allows us to "swap out" differenct implementations of these services + * for different environments, (e.g. Jest, Storybook, etc.) + */ +export interface SharedUxServices { + application: SharedUxApplicationService; + docLinks: SharedUxDocLinksService; + editors: SharedUxEditorsService; + http: SharedUxHttpService; + permissions: SharedUxUserPermissionsService; + platform: SharedUxPlatformService; +} + +/** + * A type representing a component that provides the `SharedUxServices` through a + * React Context. + */ +export type SharedUxServicesContext = FC<{}>; + +/** + * A factory function for creating one or more services. + * + * The `S` generic determines the shape of the API being produced. + * The `Parameters` generic determines what parameters are expected to + * create the service. + */ +export type ServiceFactory = (params: Parameters) => S; diff --git a/packages/kbn-shared-ux-services/tsconfig.json b/packages/kbn-shared-ux-services/tsconfig.json new file mode 100755 index 0000000000000..a8cfc2cceb08b --- /dev/null +++ b/packages/kbn-shared-ux-services/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": "src", + "stripInternal": false, + "types": [ + "jest", + "node" + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/packages/kbn-shared-ux-storybook/BUILD.bazel b/packages/kbn-shared-ux-storybook/BUILD.bazel new file mode 100644 index 0000000000000..3624a708b6cef --- /dev/null +++ b/packages/kbn-shared-ux-storybook/BUILD.bazel @@ -0,0 +1,130 @@ +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 = "kbn-shared-ux-storybook" +PKG_REQUIRE_NAME = "@kbn/shared-ux-storybook" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + "src/**/*.tsx", + ], + 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 = [ + "//packages/kbn-shared-ux-services", + "//packages/kbn-storybook", + "@npm//@storybook/react", + "@npm//@storybook/addon-actions", +] + +# 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 = [ + "//packages/kbn-shared-ux-services:npm_module_types", + "//packages/kbn-storybook:npm_module_types", + "@npm//@types/node", + "@npm//@types/jest", + "@npm//@storybook/react", + "@npm//@storybook/addon-actions", +] + +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, +) + +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/kbn-shared-ux-storybook/README.mdx b/packages/kbn-shared-ux-storybook/README.mdx new file mode 100644 index 0000000000000..cfebeedcd1ac3 --- /dev/null +++ b/packages/kbn-shared-ux-storybook/README.mdx @@ -0,0 +1,34 @@ +--- +id: kibSharedUXStorybook +slug: /kibana-dev-docs/shared-ux/packages/kbn-shared-ux-storybook +title: Shared UX Storybook +summary: The `@kbn/shared-ux-storybook` package provides Storybook assets for Shared UX and other teams. +date: 2022-03-11 +tags: ['kibana', 'dev', 'sharedUX'] +--- + +## About Shared UX Storybook + +This package provides the Storybook implementation of `@kbn/shared-ux-services` as well as the configuration for the Shared UX Storybook site. + +- `/src/services` The `@kbn/shared-ux-services` implementation. +- `src/config` The Storybook site configuration. + +## Storybook site + +Run `yarn storybook shared_ux` from `/kibana` to view the site. It pulls in `*.stories.tsx` from all Shared UX packages and plugins and combines them into a single configuration. + +## Decorator + +If you're writing stories for your own components that compose Shared UX components, you can use a pre-configured [Storybook Decorator](https://storybook.js.org/docs/react/writing-stories/decorators) in your Storybook configuration: + +```ts +// preview.ts + +import { addDecorator } from '@storybook/react'; +import { servicesDecorator } from '@kbn/shared-ux-storybook'; + +addDecorator(servicesDecorator); +``` + +This will not only expose parameters, but also wrap your story in a pre-wired `SharedUxServicesProvider`. \ No newline at end of file diff --git a/packages/kbn-shared-ux-storybook/jest.config.js b/packages/kbn-shared-ux-storybook/jest.config.js new file mode 100644 index 0000000000000..91285e025f069 --- /dev/null +++ b/packages/kbn-shared-ux-storybook/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/kbn-shared-ux-storybook'], +}; diff --git a/packages/kbn-shared-ux-storybook/package.json b/packages/kbn-shared-ux-storybook/package.json new file mode 100644 index 0000000000000..c5f22bb151431 --- /dev/null +++ b/packages/kbn-shared-ux-storybook/package.json @@ -0,0 +1,8 @@ +{ + "name": "@kbn/shared-ux-storybook", + "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/kbn-shared-ux-storybook/src/config/main.ts b/packages/kbn-shared-ux-storybook/src/config/main.ts new file mode 100644 index 0000000000000..1981ff546c353 --- /dev/null +++ b/packages/kbn-shared-ux-storybook/src/config/main.ts @@ -0,0 +1,17 @@ +/* + * 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 { defaultConfig } from '@kbn/storybook'; + +module.exports = { + ...defaultConfig, + stories: [ + '../../../kbn-shared-ux*/**/*.stories.+(tsx|mdx)', + '../../../../src/plugins/shared_ux/**/*.stories.+(tsx|mdx)', + ], +}; diff --git a/src/plugins/shared_ux/.storybook/manager.ts b/packages/kbn-shared-ux-storybook/src/config/manager.ts similarity index 100% rename from src/plugins/shared_ux/.storybook/manager.ts rename to packages/kbn-shared-ux-storybook/src/config/manager.ts diff --git a/src/plugins/shared_ux/.storybook/preview.ts b/packages/kbn-shared-ux-storybook/src/config/preview.ts similarity index 89% rename from src/plugins/shared_ux/.storybook/preview.ts rename to packages/kbn-shared-ux-storybook/src/config/preview.ts index e4be2592482f3..194a16474af2c 100644 --- a/src/plugins/shared_ux/.storybook/preview.ts +++ b/packages/kbn-shared-ux-storybook/src/config/preview.ts @@ -7,6 +7,6 @@ */ import { addDecorator } from '@storybook/react'; -import { servicesDecorator } from './decorators'; +import { servicesDecorator } from '../decorators'; addDecorator(servicesDecorator); diff --git a/src/plugins/shared_ux/.storybook/decorators.tsx b/packages/kbn-shared-ux-storybook/src/decorators.tsx similarity index 75% rename from src/plugins/shared_ux/.storybook/decorators.tsx rename to packages/kbn-shared-ux-storybook/src/decorators.tsx index c17af2cda0406..cae87a15b54dd 100644 --- a/src/plugins/shared_ux/.storybook/decorators.tsx +++ b/packages/kbn-shared-ux-storybook/src/decorators.tsx @@ -8,13 +8,15 @@ import React from 'react'; import { DecoratorFn } from '@storybook/react'; -import { ServicesProvider } from '../public/services'; -import { servicesFactory } from '../public/services/storybook'; + +import { SharedUxServicesProvider } from '@kbn/shared-ux-services'; + +import { servicesFactory } from './services'; /** * A Storybook decorator that provides the Shared UX `ServicesProvider` with Storybook-specific * implementations to stories. */ export const servicesDecorator: DecoratorFn = (storyFn) => ( - {storyFn()} + {storyFn()} ); diff --git a/packages/kbn-shared-ux-storybook/src/file_system_cache.d.ts b/packages/kbn-shared-ux-storybook/src/file_system_cache.d.ts new file mode 100644 index 0000000000000..7831c50f10178 --- /dev/null +++ b/packages/kbn-shared-ux-storybook/src/file_system_cache.d.ts @@ -0,0 +1,31 @@ +/* + * 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. + */ + +// Storybook uses this module and its types are defined in the source but not in the type output +declare module 'file-system-cache' { + interface Options { + basePath?: string; + ns?: string | string[]; + extension?: string; + } + + class FileSystemCache { + constructor(options: Options); + path(key: string): string; + fileExists(key: string): Promise; + ensureBasePath(): Promise; + get(key: string, defaultValue?: any): Promise; + getSync(key: string, defaultValue?: any): any | typeof defaultValue; + set(key: string, value: any): Promise<{ path: string }>; + setSync(key: string, value: any): this; + remove(key: string): Promise; + clear(): Promise; + save(): Promise<{ paths: string[] }>; + load(): Promise<{ files: Array<{ path: string; value: any }> }>; + } +} diff --git a/packages/kbn-shared-ux-storybook/src/index.ts b/packages/kbn-shared-ux-storybook/src/index.ts new file mode 100755 index 0000000000000..51f1c61165020 --- /dev/null +++ b/packages/kbn-shared-ux-storybook/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 { servicesDecorator } from './decorators'; + +export { + applicationServiceFactory, + docLinksServiceFactory, + editorsServiceFactory, + httpServiceFactory, + platformServiceFactory, + servicesFactory, + userPermissionsServiceFactory, +} from './services'; diff --git a/packages/kbn-shared-ux-storybook/src/mdx.d.ts b/packages/kbn-shared-ux-storybook/src/mdx.d.ts new file mode 100644 index 0000000000000..b4633af9cb87d --- /dev/null +++ b/packages/kbn-shared-ux-storybook/src/mdx.d.ts @@ -0,0 +1,14 @@ +/* + * 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. + */ + +// Importing MDX files requires a type definition not currently included in the stack. +declare module '*.mdx' { + let MDXComponent: (props: any) => JSX.Element; + // eslint-disable-next-line import/no-default-export + export default MDXComponent; +} diff --git a/src/plugins/shared_ux/public/services/storybook/application.ts b/packages/kbn-shared-ux-storybook/src/services/application.ts similarity index 79% rename from src/plugins/shared_ux/public/services/storybook/application.ts rename to packages/kbn-shared-ux-storybook/src/services/application.ts index 9b38d3b28689e..2a544445fc474 100644 --- a/src/plugins/shared_ux/public/services/storybook/application.ts +++ b/packages/kbn-shared-ux-storybook/src/services/application.ts @@ -8,10 +8,9 @@ import { BehaviorSubject } from 'rxjs'; import { action } from '@storybook/addon-actions'; -import { PluginServiceFactory } from '../types'; -import { SharedUXApplicationService } from '../application'; +import { ServiceFactory, SharedUxApplicationService } from '@kbn/shared-ux-services'; -export type ApplicationServiceFactory = PluginServiceFactory; +export type ApplicationServiceFactory = ServiceFactory; /** * A factory function for creating for creating a storybook implementation of `SharedUXApplicationService`. diff --git a/packages/kbn-shared-ux-storybook/src/services/doc_links.ts b/packages/kbn-shared-ux-storybook/src/services/doc_links.ts new file mode 100644 index 0000000000000..5ae1dcccc3664 --- /dev/null +++ b/packages/kbn-shared-ux-storybook/src/services/doc_links.ts @@ -0,0 +1,21 @@ +/* + * 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 { ServiceFactory, SharedUxDocLinksService } from '@kbn/shared-ux-services'; + +/** + * A factory function for creating a Storybook implementation of `SharedUxDocLinksService`. + */ +export type SharedUxDocLinksServiceFactory = ServiceFactory; + +/** + * A factory function for creating a Storybook implementation of `SharedUxDocLinksService`. + */ +export const docLinksServiceFactory: SharedUxDocLinksServiceFactory = () => ({ + dataViewsDocLink: 'https://www.elastic.co/guide/en/kibana/master/data-views.html', +}); diff --git a/packages/kbn-shared-ux-storybook/src/services/editors.ts b/packages/kbn-shared-ux-storybook/src/services/editors.ts new file mode 100644 index 0000000000000..69b9d7062da94 --- /dev/null +++ b/packages/kbn-shared-ux-storybook/src/services/editors.ts @@ -0,0 +1,22 @@ +/* + * 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 { ServiceFactory, SharedUxEditorsService } from '@kbn/shared-ux-services'; + +/** + * A factory function for creating a Storybook implementation of `SharedUxEditorsService`. + */ +export type SharedUxEditorsServiceFactory = ServiceFactory; + +/** + * A factory function for creating a Storybook implementation of `SharedUxEditorsService`. + */ +export const editorsServiceFactory: SharedUxEditorsServiceFactory = () => ({ + openDataViewEditor: action('openEditor') as SharedUxEditorsService['openDataViewEditor'], +}); diff --git a/src/plugins/shared_ux/public/services/storybook/http.ts b/packages/kbn-shared-ux-storybook/src/services/http.ts similarity index 74% rename from src/plugins/shared_ux/public/services/storybook/http.ts rename to packages/kbn-shared-ux-storybook/src/services/http.ts index d5a04d4587967..f44fb10566dc3 100644 --- a/src/plugins/shared_ux/public/services/storybook/http.ts +++ b/packages/kbn-shared-ux-storybook/src/services/http.ts @@ -8,17 +8,16 @@ import { action } from '@storybook/addon-actions'; -import { PluginServiceFactory } from '../types'; -import { SharedUXHttpService } from '../http'; +import { ServiceFactory, SharedUxHttpService } from '@kbn/shared-ux-services'; /** * A factory function for creating a Storybook-based implementation of `SharedUXHttpService`. */ -export type HttpServiceFactory = PluginServiceFactory; +export type HttpServiceFactory = ServiceFactory; /** * A factory function for creating a Storybook-based implementation of `SharedUXHttpService`. */ export const httpServiceFactory: HttpServiceFactory = () => ({ - addBasePath: action('addBasePath') as SharedUXHttpService['addBasePath'], + addBasePath: action('addBasePath') as SharedUxHttpService['addBasePath'], }); diff --git a/src/plugins/shared_ux/public/services/storybook/index.ts b/packages/kbn-shared-ux-storybook/src/services/index.ts similarity index 61% rename from src/plugins/shared_ux/public/services/storybook/index.ts rename to packages/kbn-shared-ux-storybook/src/services/index.ts index 878df9ca2beba..2de34f3392312 100644 --- a/src/plugins/shared_ux/public/services/storybook/index.ts +++ b/packages/kbn-shared-ux-storybook/src/services/index.ts @@ -6,23 +6,30 @@ * Side Public License, v 1. */ -import type { SharedUXServices } from '../.'; -import { PluginServiceFactory } from '../types'; -import { platformServiceFactory } from './platform'; -import { editorsServiceFactory } from './editors'; -import { userPermissionsServiceFactory } from './permissions'; +import type { ServiceFactory, SharedUxServices } from '@kbn/shared-ux-services'; + +import { applicationServiceFactory } from './application'; import { docLinksServiceFactory } from './doc_links'; +import { editorsServiceFactory } from './editors'; import { httpServiceFactory } from './http'; -import { applicationServiceFactory } from './application'; +import { platformServiceFactory } from './platform'; +import { userPermissionsServiceFactory } from './permissions'; + +export { applicationServiceFactory } from './application'; +export { docLinksServiceFactory } from './doc_links'; +export { editorsServiceFactory } from './editors'; +export { httpServiceFactory } from './http'; +export { platformServiceFactory } from './platform'; +export { userPermissionsServiceFactory } from './permissions'; /** - * A factory function for creating a Storybook-based implementation of `SharedUXServices`. + * A factory function for creating a Storybook implementation of `SharedUxServices`. */ -export const servicesFactory: PluginServiceFactory = (params) => ({ - platform: platformServiceFactory(params), - permissions: userPermissionsServiceFactory(), - editors: editorsServiceFactory(), +export const servicesFactory: ServiceFactory = (params) => ({ + application: applicationServiceFactory(), docLinks: docLinksServiceFactory(), + editors: editorsServiceFactory(), http: httpServiceFactory(params), - application: applicationServiceFactory(), + permissions: userPermissionsServiceFactory(), + platform: platformServiceFactory(params), }); diff --git a/packages/kbn-shared-ux-storybook/src/services/permissions.ts b/packages/kbn-shared-ux-storybook/src/services/permissions.ts new file mode 100644 index 0000000000000..5d00ac3ee1cb2 --- /dev/null +++ b/packages/kbn-shared-ux-storybook/src/services/permissions.ts @@ -0,0 +1,22 @@ +/* + * 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 { ServiceFactory, SharedUxUserPermissionsService } from '@kbn/shared-ux-services'; + +/** + * A factory function for creating a Storybook implementation of `SharedUxUserPermissionsService`. + */ +export type SharedUxUserPermissionsServiceFactory = ServiceFactory; + +/** + * A factory function for creating a Storybook implementation of `SharedUxUserPermissionsService`. + */ +export const userPermissionsServiceFactory: SharedUxUserPermissionsServiceFactory = () => ({ + canCreateNewDataView: true, + canAccessFleet: true, +}); diff --git a/src/plugins/shared_ux/public/services/storybook/platform.ts b/packages/kbn-shared-ux-storybook/src/services/platform.ts similarity index 58% rename from src/plugins/shared_ux/public/services/storybook/platform.ts rename to packages/kbn-shared-ux-storybook/src/services/platform.ts index 8d7645ee441ca..2a1cb6c3ff42b 100644 --- a/src/plugins/shared_ux/public/services/storybook/platform.ts +++ b/packages/kbn-shared-ux-storybook/src/services/platform.ts @@ -7,17 +7,15 @@ */ import { action } from '@storybook/addon-actions'; - -import { PluginServiceFactory } from '../types'; -import { SharedUXPlatformService } from '../platform'; +import { ServiceFactory, SharedUxPlatformService } from '@kbn/shared-ux-services'; /** - * A factory function for creating a Storybook-based implementation of `SharedUXPlatformService`. + * A factory function for creating a Storybook implementation of `SharedUxPlatformService`. */ -export type PlatformServiceFactory = PluginServiceFactory; +export type PlatformServiceFactory = ServiceFactory; /** - * A factory function for creating a Storybook-based implementation of `SharedUXPlatformService`. + * A factory function for creating a Storybook implementation of `SharedUxPlatformService`. */ export const platformServiceFactory: PlatformServiceFactory = () => ({ setIsFullscreen: action('setIsChromeVisible'), diff --git a/packages/kbn-shared-ux-storybook/tsconfig.json b/packages/kbn-shared-ux-storybook/tsconfig.json new file mode 100644 index 0000000000000..a8cfc2cceb08b --- /dev/null +++ b/packages/kbn-shared-ux-storybook/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": "src", + "stripInternal": false, + "types": [ + "jest", + "node" + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/packages/kbn-shared-ux-utility/BUILD.bazel b/packages/kbn-shared-ux-utility/BUILD.bazel new file mode 100644 index 0000000000000..b4008aa43f1ac --- /dev/null +++ b/packages/kbn-shared-ux-utility/BUILD.bazel @@ -0,0 +1,130 @@ +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 = "kbn-shared-ux-utility" +PKG_REQUIRE_NAME = "@kbn/shared-ux-utility" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + "src/**/*.tsx", + ], + 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//@emotion/css", + "@npm//@emotion/react", + "@npm//@elastic/eui", +] + +# 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", + "@npm//@emotion/react", + "@npm//@emotion/css", + "@npm//@elastic/eui", +] + +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, +) + +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/kbn-shared-ux-utility/README.mdx b/packages/kbn-shared-ux-utility/README.mdx new file mode 100644 index 0000000000000..a3a3ee965f699 --- /dev/null +++ b/packages/kbn-shared-ux-utility/README.mdx @@ -0,0 +1,14 @@ +--- +id: kibSharedUXUtility +slug: /kibana-dev-docs/shared-ux/packages/kbn-shared-ux-utility +title: Shared UX Utilities +summary: The `@kbn/shared-ux-utility` package contains a set of React, DOM and other utilities. +date: 2022-03-11 +tags: ['kibana', 'dev', 'sharedUX'] +--- + +## About Shared UX Utility + +At present, this package is currently a "catch-all" for universally-shared utilities. View the specific documentation for each utility for + +> Important: do not add new utilities to this package without considering if a different home is more appropriate. Reach out to the Shared UX team for help. \ No newline at end of file diff --git a/packages/kbn-shared-ux-utility/jest.config.js b/packages/kbn-shared-ux-utility/jest.config.js new file mode 100644 index 0000000000000..3696855dc86b5 --- /dev/null +++ b/packages/kbn-shared-ux-utility/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/kbn-shared-ux-utility'], +}; diff --git a/packages/kbn-shared-ux-utility/package.json b/packages/kbn-shared-ux-utility/package.json new file mode 100644 index 0000000000000..dca0f7758ddbc --- /dev/null +++ b/packages/kbn-shared-ux-utility/package.json @@ -0,0 +1,8 @@ +{ + "name": "@kbn/shared-ux-utility", + "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/src/plugins/shared_ux/public/components/utility/fallback.tsx b/packages/kbn-shared-ux-utility/src/fallback.tsx similarity index 100% rename from src/plugins/shared_ux/public/components/utility/fallback.tsx rename to packages/kbn-shared-ux-utility/src/fallback.tsx diff --git a/src/plugins/shared_ux/public/components/utility/index.ts b/packages/kbn-shared-ux-utility/src/index.ts similarity index 87% rename from src/plugins/shared_ux/public/components/utility/index.ts rename to packages/kbn-shared-ux-utility/src/index.ts index 4e930810a6895..d6c35ea3702ae 100644 --- a/src/plugins/shared_ux/public/components/utility/index.ts +++ b/packages/kbn-shared-ux-utility/src/index.ts @@ -8,3 +8,4 @@ export { Fallback } from './fallback'; export { withSuspense } from './with_suspense'; +export { getClosestLink, hasActiveModifierKey } from './utils'; diff --git a/src/plugins/shared_ux/public/components/utility/utils.test.ts b/packages/kbn-shared-ux-utility/src/utils.test.ts similarity index 100% rename from src/plugins/shared_ux/public/components/utility/utils.test.ts rename to packages/kbn-shared-ux-utility/src/utils.test.ts diff --git a/src/plugins/shared_ux/public/components/utility/utils.ts b/packages/kbn-shared-ux-utility/src/utils.ts similarity index 84% rename from src/plugins/shared_ux/public/components/utility/utils.ts rename to packages/kbn-shared-ux-utility/src/utils.ts index 0ac501d160815..e26f677c031a2 100644 --- a/src/plugins/shared_ux/public/components/utility/utils.ts +++ b/packages/kbn-shared-ux-utility/src/utils.ts @@ -6,17 +6,18 @@ * Side Public License, v 1. */ -import React from 'react'; +import type { MouseEvent } from 'react'; /** * Returns true if any modifier key is active on the event, false otherwise. */ -export const hasActiveModifierKey = (event: React.MouseEvent): boolean => { +export const hasActiveModifierKey = (event: MouseEvent): boolean => { return event.metaKey || event.altKey || event.ctrlKey || event.shiftKey; }; /** - * Returns the closest anchor (``) element in the element parents (self included) up to the given container (excluded), or undefined if none is found. + * Returns the closest anchor (``) element in the element parents (self included) up + * to the given container (excluded), or undefined if none is found. */ export const getClosestLink = ( element: HTMLElement | null | undefined, diff --git a/src/plugins/shared_ux/public/components/utility/with_suspense.tsx b/packages/kbn-shared-ux-utility/src/with_suspense.tsx similarity index 100% rename from src/plugins/shared_ux/public/components/utility/with_suspense.tsx rename to packages/kbn-shared-ux-utility/src/with_suspense.tsx diff --git a/packages/kbn-shared-ux-utility/tsconfig.json b/packages/kbn-shared-ux-utility/tsconfig.json new file mode 100644 index 0000000000000..cca91264519cc --- /dev/null +++ b/packages/kbn-shared-ux-utility/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": "src", + "stripInternal": false, + "types": [ + "jest", + "node", + "@emotion/react/types/css-prop" + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav.test.tsx.snap b/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav.test.tsx.snap index a16c15555f5e5..99d116b1dd957 100644 --- a/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav.test.tsx.snap +++ b/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav.test.tsx.snap @@ -404,6 +404,7 @@ exports[`CollapsibleNav renders links grouped by category 1`] = ` role={null} >

"`; +exports[`FlyoutService openFlyout() renders a flyout to the DOM 2`] = `"
Flyout content
"`; exports[`FlyoutService openFlyout() with a currently active flyout replaces the current flyout with a new one 1`] = ` Array [ @@ -199,4 +199,4 @@ Array [ ] `; -exports[`FlyoutService openFlyout() with a currently active flyout replaces the current flyout with a new one 2`] = `"
Flyout content 2
"`; +exports[`FlyoutService openFlyout() with a currently active flyout replaces the current flyout with a new one 2`] = `"
Flyout content 2
"`; diff --git a/src/core/server/saved_objects/migrations/actions/integration_tests/actions.test.ts b/src/core/server/saved_objects/migrations/actions/integration_tests/actions.test.ts index 3f7a2e9c822aa..fb14a0c8b3a01 100644 --- a/src/core/server/saved_objects/migrations/actions/integration_tests/actions.test.ts +++ b/src/core/server/saved_objects/migrations/actions/integration_tests/actions.test.ts @@ -896,8 +896,7 @@ describe('migration actions', () => { `); }); - // Failing ES Promotion: https://github.com/elastic/kibana/issues/127654 - it.skip('resolves left wait_for_task_completion_timeout when the task does not finish within the timeout', async () => { + it('resolves left wait_for_task_completion_timeout when the task does not finish within the timeout', async () => { await waitForIndexStatusYellow({ client, index: '.kibana_1', @@ -918,8 +917,8 @@ describe('migration actions', () => { _tag: 'Left', left: { error: expect.any(errors.ResponseError), - message: expect.stringMatching( - /\[timeout_exception\] Timed out waiting for completion of \[org.elasticsearch.index.reindex.BulkByScrollTask/ + message: expect.stringContaining( + '[timeout_exception] Timed out waiting for completion of [Task' ), type: 'wait_for_task_completion_timeout', }, @@ -1262,8 +1261,7 @@ describe('migration actions', () => { await expect(task()).rejects.toThrow('index_not_found_exception'); }); - // Failing ES Promotion: https://github.com/elastic/kibana/issues/127654 - it.skip('resolves left wait_for_task_completion_timeout when the task does not complete within the timeout', async () => { + it('resolves left wait_for_task_completion_timeout when the task does not complete within the timeout', async () => { const res = (await pickupUpdatedMappings( client, '.kibana_1' @@ -1279,8 +1277,8 @@ describe('migration actions', () => { _tag: 'Left', left: { error: expect.any(errors.ResponseError), - message: expect.stringMatching( - /\[timeout_exception\] Timed out waiting for completion of \[org.elasticsearch.index.reindex.BulkByScrollTask/ + message: expect.stringContaining( + '[timeout_exception] Timed out waiting for completion of [Task' ), type: 'wait_for_task_completion_timeout', }, diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index d8e9f9cc7e114..d1ae8f595c8c2 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -77,6 +77,6 @@ export const LICENSE_OVERRIDES = { 'jsts@1.6.2': ['Eclipse Distribution License - v 1.0'], // cf. https://github.com/bjornharrtell/jsts '@mapbox/jsonlint-lines-primitives@2.0.2': ['MIT'], // license in readme https://github.com/tmcw/jsonlint '@elastic/ems-client@8.1.0': ['Elastic License 2.0'], - '@elastic/eui@48.1.1': ['SSPL-1.0 OR Elastic License 2.0'], + '@elastic/eui@51.1.0': ['SSPL-1.0 OR Elastic License 2.0'], 'language-subtag-registry@0.3.21': ['CC-BY-4.0'], // retired ODC‑By license https://github.com/mattcg/language-subtag-registry }; diff --git a/src/dev/precommit_hook/casing_check_config.js b/src/dev/precommit_hook/casing_check_config.js index eb65e0b752174..8aa2d6f1cfe55 100644 --- a/src/dev/precommit_hook/casing_check_config.js +++ b/src/dev/precommit_hook/casing_check_config.js @@ -146,10 +146,10 @@ export const TEMPORARILY_IGNORED_PATHS = [ 'x-pack/plugins/monitoring/public/icons/health-green.svg', 'x-pack/plugins/monitoring/public/icons/health-red.svg', 'x-pack/plugins/monitoring/public/icons/health-yellow.svg', - 'x-pack/plugins/reporting/server/export_types/common/assets/fonts/noto/NotoSansCJKtc-Medium.ttf', - 'x-pack/plugins/reporting/server/export_types/common/assets/fonts/noto/NotoSansCJKtc-Regular.ttf', - 'x-pack/plugins/reporting/server/export_types/common/assets/fonts/roboto/Roboto-Italic.ttf', - 'x-pack/plugins/reporting/server/export_types/common/assets/fonts/roboto/Roboto-Medium.ttf', - 'x-pack/plugins/reporting/server/export_types/common/assets/fonts/roboto/Roboto-Regular.ttf', - 'x-pack/plugins/reporting/server/export_types/common/assets/img/logo-grey.png', + 'x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/assets/fonts/noto/NotoSansCJKtc-Medium.ttf', + 'x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/assets/fonts/noto/NotoSansCJKtc-Regular.ttf', + 'x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/assets/fonts/roboto/Roboto-Italic.ttf', + 'x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/assets/fonts/roboto/Roboto-Medium.ttf', + 'x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/assets/fonts/roboto/Roboto-Regular.ttf', + 'x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/assets/img/logo-grey.png', ]; diff --git a/src/dev/storybook/aliases.ts b/src/dev/storybook/aliases.ts index db0791f41b0a7..eb7f75c27661f 100644 --- a/src/dev/storybook/aliases.ts +++ b/src/dev/storybook/aliases.ts @@ -35,6 +35,6 @@ export const storybookAliases = { observability: 'x-pack/plugins/observability/.storybook', presentation: 'src/plugins/presentation_util/storybook', security_solution: 'x-pack/plugins/security_solution/.storybook', - shared_ux: 'src/plugins/shared_ux/.storybook', + shared_ux: 'packages/kbn-shared-ux-storybook/src/config', ui_actions_enhanced: 'x-pack/plugins/ui_actions_enhanced/.storybook', }; diff --git a/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.tsx b/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.tsx index 7d0e8ad66511d..2121221cc9585 100644 --- a/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.tsx +++ b/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.tsx @@ -288,7 +288,9 @@ export const HeatmapComponent: FC = memo( return null; } - let chartData = table.rows.filter((v) => typeof v[valueAccessor!] === 'number'); + let chartData = table.rows.filter( + (v) => v[valueAccessor!] === null || typeof v[valueAccessor!] === 'number' + ); if (!chartData || !chartData.length) { return ; } diff --git a/src/plugins/console/server/routes/api/console/proxy/create_handler.ts b/src/plugins/console/server/routes/api/console/proxy/create_handler.ts index bdf9426a82107..815c507b763f7 100644 --- a/src/plugins/console/server/routes/api/console/proxy/create_handler.ts +++ b/src/plugins/console/server/routes/api/console/proxy/create_handler.ts @@ -31,6 +31,14 @@ import { RouteDependencies } from '../../../'; import { Body, Query } from './validation_config'; function toURL(base: string, path: string) { + const [p, query = ''] = path.split('?'); + + // if there is a '+' sign in query e.g. ?q=create_date:[2020-05-10T08:00:00.000+08:00 TO *] + // node url encodes it as a whitespace which results in a faulty request + // we need to replace '+' with '%2b' to encode it correctly + if (/\+/g.test(query)) { + path = `${p}?${query.replace(/\+/g, '%2b')}`; + } const urlResult = new url.URL(`${trimEnd(base, '/')}/${trimStart(path, '/')}`); // Appending pretty here to have Elasticsearch do the JSON formatting, as doing // in JS can lead to data loss (7.0 will get munged into 7, thus losing indication of @@ -116,7 +124,7 @@ export const createHandler = }: RouteDependencies): RequestHandler => async (ctx, request, response) => { const { body, query } = request; - const { path, method, withProductOrigin } = query; + const { method, path, withProductOrigin } = query; if (kibanaVersion.major < 8) { // The "console.proxyFilter" setting in kibana.yaml has been deprecated in 8.x diff --git a/src/plugins/console/server/routes/api/console/proxy/query_string.test.ts b/src/plugins/console/server/routes/api/console/proxy/query_string.test.ts index be4f1dbab942f..3f7ba81c33c03 100644 --- a/src/plugins/console/server/routes/api/console/proxy/query_string.test.ts +++ b/src/plugins/console/server/routes/api/console/proxy/query_string.test.ts @@ -16,6 +16,8 @@ import { createHandler } from './create_handler'; describe('Console Proxy Route', () => { let request: (method: string, path: string) => Promise | IKibanaResponse; + const proxyRequestMock = requestModule.proxyRequest as jest.Mock; + beforeEach(() => { (requestModule.proxyRequest as jest.Mock).mockResolvedValue(createResponseStub('foo')); @@ -39,7 +41,7 @@ describe('Console Proxy Route', () => { describe('contains full url', () => { it('treats the url as a path', async () => { await request('GET', 'http://evil.com/test'); - expect((requestModule.proxyRequest as jest.Mock).mock.calls.length).toBe(1); + expect(proxyRequestMock.mock.calls.length).toBe(1); const [[args]] = (requestModule.proxyRequest as jest.Mock).mock.calls; expect(args.uri.href).toBe('http://localhost:9200/http://evil.com/test?pretty=true'); }); @@ -47,7 +49,7 @@ describe('Console Proxy Route', () => { describe('starts with a slash', () => { it('combines well with the base url', async () => { await request('GET', '/index/id'); - expect((requestModule.proxyRequest as jest.Mock).mock.calls.length).toBe(1); + expect(proxyRequestMock.mock.calls.length).toBe(1); const [[args]] = (requestModule.proxyRequest as jest.Mock).mock.calls; expect(args.uri.href).toBe('http://localhost:9200/index/id?pretty=true'); }); @@ -55,11 +57,24 @@ describe('Console Proxy Route', () => { describe(`doesn't start with a slash`, () => { it('combines well with the base url', async () => { await request('GET', 'index/id'); - expect((requestModule.proxyRequest as jest.Mock).mock.calls.length).toBe(1); + expect(proxyRequestMock.mock.calls.length).toBe(1); const [[args]] = (requestModule.proxyRequest as jest.Mock).mock.calls; expect(args.uri.href).toBe('http://localhost:9200/index/id?pretty=true'); }); }); + describe('contains special characters', () => { + it('correctly encodes plus sign', async () => { + const path = '/_search?q=create_date:[2022-03-10T08:00:00.000+08:00 TO *]'; + + const { status } = await request('GET', path); + expect(status).toBe(200); + expect(proxyRequestMock.mock.calls.length).toBe(1); + const [[args]] = proxyRequestMock.mock.calls; + expect(args.uri.search).toEqual( + '?q=create_date%3A%5B2022-03-10T08%3A00%3A00.000%2B08%3A00+TO+*%5D&pretty=true' + ); + }); + }); }); }); }); diff --git a/src/plugins/data/common/search/aggs/buckets/histogram.test.ts b/src/plugins/data/common/search/aggs/buckets/histogram.test.ts index ef5cd85e6f5a2..afeb8b47372bd 100644 --- a/src/plugins/data/common/search/aggs/buckets/histogram.test.ts +++ b/src/plugins/data/common/search/aggs/buckets/histogram.test.ts @@ -74,6 +74,9 @@ describe('Histogram Agg', () => { "chain": Array [ Object { "arguments": Object { + "autoExtendBounds": Array [ + false, + ], "enabled": Array [ true, ], @@ -399,6 +402,20 @@ describe('Histogram Agg', () => { expect(output.extended_bounds).toHaveProperty('max', 100); }); + test('writes when auto bounds and autoExtendBounds are set', () => { + const aggConfigs = getAggConfigs({ + autoExtendBounds: true, + field: { + name: 'field', + }, + }); + (aggConfigs.aggs[0] as IBucketHistogramAggConfig).setAutoBounds({ min: 0, max: 1000 }); + const output = aggConfigs.aggs[0].toDsl()[BUCKET_TYPES.HISTOGRAM]; + + expect(output.extended_bounds).toHaveProperty('min', 0); + expect(output.extended_bounds).toHaveProperty('max', 1000); + }); + test('does not write when nothing is set', () => { const output = getParams({ has_extended_bounds: true, diff --git a/src/plugins/data/common/search/aggs/buckets/histogram.ts b/src/plugins/data/common/search/aggs/buckets/histogram.ts index db3ac11ae3535..2aba5e81f1e7a 100644 --- a/src/plugins/data/common/search/aggs/buckets/histogram.ts +++ b/src/plugins/data/common/search/aggs/buckets/histogram.ts @@ -47,6 +47,7 @@ export interface AggParamsHistogram extends BaseAggParams { min_doc_count?: boolean; has_extended_bounds?: boolean; extended_bounds?: ExtendedBounds; + autoExtendBounds?: boolean; } export const getHistogramBucketAgg = ({ @@ -97,6 +98,14 @@ export const getHistogramBucketAgg = ({ default: null, write: () => {}, }, + { + /* + * Set to true to extend bounds to the domain of the data. This makes sure each interval bucket within these bounds will create a separate table row + */ + name: 'autoExtendBounds', + default: false, + write: () => {}, + }, { name: 'interval', default: autoInterval, @@ -202,6 +211,8 @@ export const getHistogramBucketAgg = ({ if (aggConfig.params.has_extended_bounds && (min || min === 0) && (max || max === 0)) { output.params.extended_bounds = { min, max }; + } else if (aggConfig.params.autoExtendBounds && aggConfig.getAutoBounds()) { + output.params.extended_bounds = aggConfig.getAutoBounds(); } }, shouldShow: (aggConfig: IBucketAggConfig) => aggConfig.params.has_extended_bounds, diff --git a/src/plugins/data/common/search/aggs/buckets/histogram_fn.test.ts b/src/plugins/data/common/search/aggs/buckets/histogram_fn.test.ts index 7c86384e965a8..1f8ee808053fe 100644 --- a/src/plugins/data/common/search/aggs/buckets/histogram_fn.test.ts +++ b/src/plugins/data/common/search/aggs/buckets/histogram_fn.test.ts @@ -25,6 +25,7 @@ describe('agg_expression_functions', () => { "enabled": true, "id": undefined, "params": Object { + "autoExtendBounds": undefined, "customLabel": undefined, "extended_bounds": undefined, "field": "field", @@ -50,6 +51,7 @@ describe('agg_expression_functions', () => { maxBars: 25, min_doc_count: false, has_extended_bounds: false, + autoExtendBounds: true, extended_bounds: { type: 'extended_bounds', min: 1, @@ -62,6 +64,7 @@ describe('agg_expression_functions', () => { "enabled": true, "id": undefined, "params": Object { + "autoExtendBounds": true, "customLabel": undefined, "extended_bounds": Object { "max": 2, diff --git a/src/plugins/data/common/search/aggs/buckets/histogram_fn.ts b/src/plugins/data/common/search/aggs/buckets/histogram_fn.ts index e01b4d0267a72..f46a158844a00 100644 --- a/src/plugins/data/common/search/aggs/buckets/histogram_fn.ts +++ b/src/plugins/data/common/search/aggs/buckets/histogram_fn.ts @@ -86,6 +86,13 @@ export const aggHistogram = (): FunctionDefinition => ({ defaultMessage: 'Calculate interval to get approximately this many bars', }), }, + autoExtendBounds: { + types: ['boolean'], + help: i18n.translate('data.search.aggs.buckets.histogram.autoExtendBounds.help', { + defaultMessage: + 'Set to true to extend bounds to the domain of the data. This makes sure each interval bucket within these bounds will create a separate table row', + }), + }, has_extended_bounds: { types: ['boolean'], help: i18n.translate('data.search.aggs.buckets.histogram.hasExtendedBounds.help', { diff --git a/src/plugins/data/public/utils/table_inspector_view/components/__snapshots__/data_view.test.tsx.snap b/src/plugins/data/public/utils/table_inspector_view/components/__snapshots__/data_view.test.tsx.snap index dcaba4c3f8e19..7e7389364a9bd 100644 --- a/src/plugins/data/public/utils/table_inspector_view/components/__snapshots__/data_view.test.tsx.snap +++ b/src/plugins/data/public/utils/table_inspector_view/components/__snapshots__/data_view.test.tsx.snap @@ -911,7 +911,6 @@ exports[`Inspector Data View component should render single table without select onChange={[Function]} pagination={ Object { - "hidePerPageOptions": undefined, "pageIndex": 0, "pageSize": 20, "pageSizeOptions": Array [ @@ -919,6 +918,7 @@ exports[`Inspector Data View component should render single table without select 20, 50, ], + "showPerPageOptions": undefined, "totalItemCount": 1, } } @@ -1254,7 +1254,6 @@ exports[`Inspector Data View component should render single table without select onPageSizeChange={[Function]} pagination={ Object { - "hidePerPageOptions": undefined, "pageIndex": 0, "pageSize": 20, "pageSizeOptions": Array [ @@ -1262,6 +1261,7 @@ exports[`Inspector Data View component should render single table without select 20, 50, ], + "showPerPageOptions": undefined, "totalItemCount": 1, } } @@ -1296,9 +1296,10 @@ exports[`Inspector Data View component should render single table without select gutterSize="s" justifyContent="spaceBetween" responsive={false} + wrap={true} >
- - : - 20 + + + : + 20 + } closePopover={[Function]} @@ -2493,7 +2496,6 @@ exports[`Inspector Data View component should support multiple datatables 1`] = onChange={[Function]} pagination={ Object { - "hidePerPageOptions": undefined, "pageIndex": 0, "pageSize": 20, "pageSizeOptions": Array [ @@ -2501,6 +2503,7 @@ exports[`Inspector Data View component should support multiple datatables 1`] = 20, 50, ], + "showPerPageOptions": undefined, "totalItemCount": 1, } } @@ -2837,7 +2840,6 @@ exports[`Inspector Data View component should support multiple datatables 1`] = onPageSizeChange={[Function]} pagination={ Object { - "hidePerPageOptions": undefined, "pageIndex": 0, "pageSize": 20, "pageSizeOptions": Array [ @@ -2845,6 +2847,7 @@ exports[`Inspector Data View component should support multiple datatables 1`] = 20, 50, ], + "showPerPageOptions": undefined, "totalItemCount": 1, } } @@ -2879,9 +2882,10 @@ exports[`Inspector Data View component should support multiple datatables 1`] = gutterSize="s" justifyContent="spaceBetween" responsive={false} + wrap={true} >
- - : - 20 + + + : + 20 + } closePopover={[Function]} diff --git a/src/plugins/data_view_field_editor/public/components/field_editor/form_fields/type_field.tsx b/src/plugins/data_view_field_editor/public/components/field_editor/form_fields/type_field.tsx index 1b48cb2c82e5c..36428579a30e8 100644 --- a/src/plugins/data_view_field_editor/public/components/field_editor/form_fields/type_field.tsx +++ b/src/plugins/data_view_field_editor/public/components/field_editor/form_fields/type_field.tsx @@ -54,7 +54,6 @@ export const TypeField = ({ isDisabled = false }: Props) => { defaultMessage: 'Type select', } )} - aria-controls="runtimeFieldScript" fullWidth /> diff --git a/src/plugins/discover/public/application/main/components/field_stats_table/field_stats_table.tsx b/src/plugins/discover/public/application/main/components/field_stats_table/field_stats_table.tsx index 63e41c44e2998..ceae378be3bd6 100644 --- a/src/plugins/discover/public/application/main/components/field_stats_table/field_stats_table.tsx +++ b/src/plugins/discover/public/application/main/components/field_stats_table/field_stats_table.tsx @@ -25,7 +25,7 @@ import type { GetStateReturn } from '../../services/discover_state'; import { AvailableFields$, DataRefetch$ } from '../../utils/use_saved_search'; export interface DataVisualizerGridEmbeddableInput extends EmbeddableInput { - indexPattern: DataView; + dataView: DataView; savedSearch?: SavedSearch; query?: Query; visibleFieldNames?: string[]; @@ -148,7 +148,7 @@ export const FieldStatisticsTable = (props: FieldStatisticsTableProps) => { if (embeddable && !isErrorEmbeddable(embeddable)) { // Update embeddable whenever one of the important input changes embeddable.updateInput({ - indexPattern, + dataView: indexPattern, savedSearch, query, filters, @@ -194,7 +194,7 @@ export const FieldStatisticsTable = (props: FieldStatisticsTableProps) => { // Initialize embeddable with information available at mount const initializedEmbeddable = await factory.create({ id: 'discover_data_visualizer_grid', - indexPattern, + dataView: indexPattern, savedSearch, query, showPreviewByDefault, diff --git a/src/plugins/discover/public/application/main/components/sidebar/__snapshots__/discover_index_pattern_management.test.tsx.snap b/src/plugins/discover/public/application/main/components/sidebar/__snapshots__/discover_index_pattern_management.test.tsx.snap index a08b8f4022745..f0ffe494e8c20 100644 --- a/src/plugins/discover/public/application/main/components/sidebar/__snapshots__/discover_index_pattern_management.test.tsx.snap +++ b/src/plugins/discover/public/application/main/components/sidebar/__snapshots__/discover_index_pattern_management.test.tsx.snap @@ -707,7 +707,6 @@ exports[`Discover DataView Management renders correctly 1`] = ` aria-label="Data view settings" className="euiButtonIcon euiButtonIcon--text euiButtonIcon--empty euiButtonIcon--xSmall" data-test-subj="discoverIndexPatternActions" - disabled={false} onClick={[Function]} type="button" > diff --git a/src/plugins/shared_ux/kibana.json b/src/plugins/shared_ux/kibana.json index 308a252f70b54..540514b4ab7e7 100755 --- a/src/plugins/shared_ux/kibana.json +++ b/src/plugins/shared_ux/kibana.json @@ -9,6 +9,6 @@ "description": "A plugin providing components and services for shared user experiences in Kibana.", "server": true, "ui": true, - "requiredPlugins": ["dataViewEditor", "dataViews"], + "requiredPlugins": ["dataViewEditor"], "optionalPlugins": [] } diff --git a/src/plugins/shared_ux/public/index.ts b/src/plugins/shared_ux/public/index.ts index 5505f5ffb1e02..1dcf84eaf4991 100755 --- a/src/plugins/shared_ux/public/index.ts +++ b/src/plugins/shared_ux/public/index.ts @@ -16,6 +16,3 @@ export function plugin() { } export type { SharedUXPluginSetup, SharedUXPluginStart } from './types'; -export { ExitFullScreenButton, LazyExitFullScreenButton } from './components'; -export { NoDataViewsPage, LazyNoDataViewsPage } from './components'; -export { IconButtonGroup } from './components'; diff --git a/src/plugins/shared_ux/public/plugin.tsx b/src/plugins/shared_ux/public/plugin.tsx index 1d2840566d4d9..b91675fd88f5b 100755 --- a/src/plugins/shared_ux/public/plugin.tsx +++ b/src/plugins/shared_ux/public/plugin.tsx @@ -7,6 +7,9 @@ */ import React from 'react'; + +import { SharedUxServicesProvider } from '@kbn/shared-ux-services'; + import { CoreSetup, CoreStart, Plugin } from '../../../core/public'; import { SharedUXPluginSetup, @@ -15,8 +18,7 @@ import { SharedUXPluginSetupDeps, } from './types'; -import { ServicesProvider } from './services'; -import { servicesFactory } from './services/kibana'; +import { servicesFactory } from './services'; /** * The Kibana plugin for Shared User Experience (Shared UX). @@ -34,7 +36,7 @@ export class SharedUXPlugin implements Plugin ( - {children} + {children} ), }; } diff --git a/src/plugins/shared_ux/public/services/application.ts b/src/plugins/shared_ux/public/services/application.ts index b1901bd79c6d2..95d6d4b4d72d9 100644 --- a/src/plugins/shared_ux/public/services/application.ts +++ b/src/plugins/shared_ux/public/services/application.ts @@ -6,9 +6,20 @@ * Side Public License, v 1. */ -import { Observable } from 'rxjs'; +import { SharedUxApplicationService } from '@kbn/shared-ux-services'; -export interface SharedUXApplicationService { - navigateToUrl: (url: string) => Promise; - currentAppId$: Observable; -} +import { KibanaPluginServiceFactory } from './types'; +import { SharedUXPluginStartDeps } from '../types'; + +export type ApplicationServiceFactory = KibanaPluginServiceFactory< + SharedUxApplicationService, + SharedUXPluginStartDeps +>; + +/** + * A factory function for creating a Kibana-based implementation of `SharedUXEditorsService`. + */ +export const applicationServiceFactory: ApplicationServiceFactory = ({ coreStart }) => ({ + navigateToUrl: coreStart.application.navigateToUrl, + currentAppId$: coreStart.application.currentAppId$, +}); diff --git a/src/plugins/shared_ux/public/services/doc_links.ts b/src/plugins/shared_ux/public/services/doc_links.ts index 3c6d23bd33ae4..b457cddb7c3bc 100644 --- a/src/plugins/shared_ux/public/services/doc_links.ts +++ b/src/plugins/shared_ux/public/services/doc_links.ts @@ -5,6 +5,20 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -export interface SharedUXDocLinksService { - dataViewsDocsLink: string; -} + +import { SharedUxDocLinksService } from '@kbn/shared-ux-services'; + +import { KibanaPluginServiceFactory } from './types'; +import { SharedUXPluginStartDeps } from '../types'; + +export type DocLinksServiceFactory = KibanaPluginServiceFactory< + SharedUxDocLinksService, + SharedUXPluginStartDeps +>; + +/** + * A factory function for creating a Kibana-based implementation of `SharedUXEditorsService`. + */ +export const docLinksServiceFactory: DocLinksServiceFactory = ({ coreStart }) => ({ + dataViewsDocLink: coreStart.docLinks.links.indexPatterns?.introduction, +}); diff --git a/src/plugins/shared_ux/public/services/editors.ts b/src/plugins/shared_ux/public/services/editors.ts index 176b22a6006e1..498b42954091c 100644 --- a/src/plugins/shared_ux/public/services/editors.ts +++ b/src/plugins/shared_ux/public/services/editors.ts @@ -5,11 +5,20 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { DataView } from '../../../data_views/common'; - -export interface SharedUxDataViewEditorProps { - onSave: (dataView: DataView) => void; -} -export interface SharedUXEditorsService { - openDataViewEditor: (options: SharedUxDataViewEditorProps) => () => void; -} + +import { SharedUxEditorsService } from '@kbn/shared-ux-services'; + +import { KibanaPluginServiceFactory } from './types'; +import { SharedUXPluginStartDeps } from '../types'; + +export type EditorsServiceFactory = KibanaPluginServiceFactory< + SharedUxEditorsService, + SharedUXPluginStartDeps +>; + +/** + * A factory function for creating a Kibana-based implementation of `SharedUXEditorsService`. + */ +export const editorsServiceFactory: EditorsServiceFactory = ({ startPlugins }) => ({ + openDataViewEditor: startPlugins.dataViewEditor.openEditor, +}); diff --git a/src/plugins/shared_ux/public/services/http.ts b/src/plugins/shared_ux/public/services/http.ts index da32d659b445f..afc2f00713988 100644 --- a/src/plugins/shared_ux/public/services/http.ts +++ b/src/plugins/shared_ux/public/services/http.ts @@ -6,6 +6,19 @@ * Side Public License, v 1. */ -export interface SharedUXHttpService { - addBasePath: (url: string) => string; -} +import { SharedUxHttpService } from '@kbn/shared-ux-services'; + +import { KibanaPluginServiceFactory } from './types'; +import { SharedUXPluginStartDeps } from '../types'; + +export type HttpServiceFactory = KibanaPluginServiceFactory< + SharedUxHttpService, + SharedUXPluginStartDeps +>; + +/** + * A factory function for creating a Kibana-based implementation of `SharedUXEditorsService`. + */ +export const httpServiceFactory: HttpServiceFactory = ({ coreStart }) => ({ + addBasePath: coreStart.http.basePath.prepend, +}); diff --git a/src/plugins/shared_ux/public/services/kibana/index.ts b/src/plugins/shared_ux/public/services/index.ts similarity index 85% rename from src/plugins/shared_ux/public/services/kibana/index.ts rename to src/plugins/shared_ux/public/services/index.ts index 0df8604379b4f..358a2b8035ecf 100644 --- a/src/plugins/shared_ux/public/services/kibana/index.ts +++ b/src/plugins/shared_ux/public/services/index.ts @@ -6,9 +6,11 @@ * Side Public License, v 1. */ -import type { SharedUXServices } from '..'; -import type { SharedUXPluginStartDeps } from '../../types'; -import type { KibanaPluginServiceFactory } from '../types'; +import { SharedUxServices } from '@kbn/shared-ux-services'; + +import type { SharedUXPluginStartDeps } from '../types'; +import type { KibanaPluginServiceFactory } from './types'; + import { platformServiceFactory } from './platform'; import { userPermissionsServiceFactory } from './permissions'; import { editorsServiceFactory } from './editors'; @@ -20,7 +22,7 @@ import { applicationServiceFactory } from './application'; * A factory function for creating a Kibana-based implementation of `SharedUXServices`. */ export const servicesFactory: KibanaPluginServiceFactory< - SharedUXServices, + SharedUxServices, SharedUXPluginStartDeps > = (params) => ({ platform: platformServiceFactory(params), diff --git a/src/plugins/shared_ux/public/services/index.tsx b/src/plugins/shared_ux/public/services/index.tsx deleted file mode 100644 index e83e1eab4b95d..0000000000000 --- a/src/plugins/shared_ux/public/services/index.tsx +++ /dev/null @@ -1,70 +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, { FC, createContext, useContext } from 'react'; -import { SharedUXPlatformService } from './platform'; -import { servicesFactory } from './stub'; -import { SharedUXUserPermissionsService } from './permissions'; -import { SharedUXEditorsService } from './editors'; -import { SharedUXDocLinksService } from './doc_links'; -import { SharedUXHttpService } from './http'; -import { SharedUXApplicationService } from './application'; - -/** - * A collection of services utilized by SharedUX. This serves as a thin - * abstraction layer between services provided by Kibana and other plugins - * while allowing this plugin to be developed independently of those contracts. - * - * It also allows us to "swap out" differenct implementations of these services - * for different environments, (e.g. Jest, Storybook, etc.) - */ -export interface SharedUXServices { - platform: SharedUXPlatformService; - permissions: SharedUXUserPermissionsService; - editors: SharedUXEditorsService; - docLinks: SharedUXDocLinksService; - http: SharedUXHttpService; - application: SharedUXApplicationService; -} - -// The React Context used to provide the services to the SharedUX components. -const ServicesContext = createContext(servicesFactory()); - -/** - * The `React.Context` Provider component for the `SharedUXServices` context. Any - * plugin or environment that consumes SharedUX components needs to wrap their React - * tree with this provider. - * - * Within a plugin, you can use the `ServicesContext` provided by the SharedUX plugin start - * lifeycle method. - */ -export const ServicesProvider: FC = ({ children, ...services }) => ( - {children} -); - -/** - * React hook for accessing the pre-wired `SharedUXServices`. - */ -export function useServices() { - return useContext(ServicesContext); -} - -/** - * React hook for accessing the pre-wired `SharedUXPlatformService`. - */ -export const usePlatformService = () => useServices().platform; - -export const usePermissions = () => useServices().permissions; - -export const useEditors = () => useServices().editors; - -export const useDocLinks = () => useServices().docLinks; - -export const useHttp = () => useServices().http; - -export const useApplication = () => useServices().application; diff --git a/src/plugins/shared_ux/public/services/kibana/application.ts b/src/plugins/shared_ux/public/services/kibana/application.ts deleted file mode 100644 index dfb13e6088270..0000000000000 --- a/src/plugins/shared_ux/public/services/kibana/application.ts +++ /dev/null @@ -1,24 +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 { KibanaPluginServiceFactory } from '../types'; -import { SharedUXPluginStartDeps } from '../../types'; -import { SharedUXApplicationService } from '../application'; - -export type ApplicationServiceFactory = KibanaPluginServiceFactory< - SharedUXApplicationService, - SharedUXPluginStartDeps ->; - -/** - * A factory function for creating a Kibana-based implementation of `SharedUXEditorsService`. - */ -export const applicationServiceFactory: ApplicationServiceFactory = ({ coreStart }) => ({ - navigateToUrl: coreStart.application.navigateToUrl, - currentAppId$: coreStart.application.currentAppId$, -}); diff --git a/src/plugins/shared_ux/public/services/kibana/doc_links.ts b/src/plugins/shared_ux/public/services/kibana/doc_links.ts deleted file mode 100644 index eb25114a188a2..0000000000000 --- a/src/plugins/shared_ux/public/services/kibana/doc_links.ts +++ /dev/null @@ -1,23 +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 { KibanaPluginServiceFactory } from '../types'; -import { SharedUXPluginStartDeps } from '../../types'; -import { SharedUXDocLinksService } from '../doc_links'; - -export type DocLinksServiceFactory = KibanaPluginServiceFactory< - SharedUXDocLinksService, - SharedUXPluginStartDeps ->; - -/** - * A factory function for creating a Kibana-based implementation of `SharedUXEditorsService`. - */ -export const docLinksServiceFactory: DocLinksServiceFactory = ({ coreStart }) => ({ - dataViewsDocsLink: coreStart.docLinks.links.indexPatterns?.introduction, -}); diff --git a/src/plugins/shared_ux/public/services/kibana/editors.ts b/src/plugins/shared_ux/public/services/kibana/editors.ts deleted file mode 100644 index 0f8082d7d00e2..0000000000000 --- a/src/plugins/shared_ux/public/services/kibana/editors.ts +++ /dev/null @@ -1,23 +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 { KibanaPluginServiceFactory } from '../types'; -import { SharedUXEditorsService } from '../editors'; -import { SharedUXPluginStartDeps } from '../../types'; - -export type EditorsServiceFactory = KibanaPluginServiceFactory< - SharedUXEditorsService, - SharedUXPluginStartDeps ->; - -/** - * A factory function for creating a Kibana-based implementation of `SharedUXEditorsService`. - */ -export const editorsServiceFactory: EditorsServiceFactory = ({ startPlugins }) => ({ - openDataViewEditor: startPlugins.dataViewEditor.openEditor, -}); diff --git a/src/plugins/shared_ux/public/services/kibana/http.ts b/src/plugins/shared_ux/public/services/kibana/http.ts deleted file mode 100644 index 0947d416724df..0000000000000 --- a/src/plugins/shared_ux/public/services/kibana/http.ts +++ /dev/null @@ -1,23 +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 { KibanaPluginServiceFactory } from '../types'; -import { SharedUXHttpService } from '../http'; -import { SharedUXPluginStartDeps } from '../../types'; - -export type HttpServiceFactory = KibanaPluginServiceFactory< - SharedUXHttpService, - SharedUXPluginStartDeps ->; - -/** - * A factory function for creating a Kibana-based implementation of `SharedUXEditorsService`. - */ -export const httpServiceFactory: HttpServiceFactory = ({ coreStart, startPlugins }) => ({ - addBasePath: coreStart.http.basePath.prepend, -}); diff --git a/src/plugins/shared_ux/public/services/kibana/permissions.ts b/src/plugins/shared_ux/public/services/kibana/permissions.ts deleted file mode 100644 index 5b1cedd51e969..0000000000000 --- a/src/plugins/shared_ux/public/services/kibana/permissions.ts +++ /dev/null @@ -1,27 +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 { KibanaPluginServiceFactory } from '../types'; -import { SharedUXPluginStartDeps } from '../../types'; -import { SharedUXUserPermissionsService } from '../permissions'; - -export type UserPermissionsServiceFactory = KibanaPluginServiceFactory< - SharedUXUserPermissionsService, - SharedUXPluginStartDeps ->; - -/** - * A factory function for creating a Kibana-based implementation of `SharedUXPermissionsService`. - */ -export const userPermissionsServiceFactory: UserPermissionsServiceFactory = ({ - coreStart, - startPlugins, -}) => ({ - canCreateNewDataView: startPlugins.dataViewEditor.userPermissions.editDataView(), - canAccessFleet: coreStart.application.capabilities.navLinks.integrations, -}); diff --git a/src/plugins/shared_ux/public/services/kibana/platform.ts b/src/plugins/shared_ux/public/services/kibana/platform.ts deleted file mode 100644 index 9872149ee02f2..0000000000000 --- a/src/plugins/shared_ux/public/services/kibana/platform.ts +++ /dev/null @@ -1,26 +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 { SharedUXPluginStartDeps } from '../../types'; -import { KibanaPluginServiceFactory } from '../types'; -import { SharedUXPlatformService } from '../platform'; - -/** - * A factory function for creating a Kibana-based implementation of `SharedUXPlatformService`. - */ -export type PlatformServiceFactory = KibanaPluginServiceFactory< - SharedUXPlatformService, - SharedUXPluginStartDeps ->; - -/** - * A factory function for creating a Kibana-based implementation of `SharedUXPlatformService`. - */ -export const platformServiceFactory: PlatformServiceFactory = ({ coreStart }) => ({ - setIsFullscreen: (isVisible: boolean) => coreStart.chrome.setIsVisible(isVisible), -}); diff --git a/src/plugins/shared_ux/public/services/permissions.ts b/src/plugins/shared_ux/public/services/permissions.ts index 8e8f5a54341d6..694405b5c6610 100644 --- a/src/plugins/shared_ux/public/services/permissions.ts +++ b/src/plugins/shared_ux/public/services/permissions.ts @@ -6,7 +6,22 @@ * Side Public License, v 1. */ -export interface SharedUXUserPermissionsService { - canCreateNewDataView: boolean; - canAccessFleet: boolean; -} +import { SharedUxUserPermissionsService } from '@kbn/shared-ux-services'; +import { KibanaPluginServiceFactory } from './types'; +import { SharedUXPluginStartDeps } from '../types'; + +export type UserPermissionsServiceFactory = KibanaPluginServiceFactory< + SharedUxUserPermissionsService, + SharedUXPluginStartDeps +>; + +/** + * A factory function for creating a Kibana-based implementation of `SharedUXPermissionsService`. + */ +export const userPermissionsServiceFactory: UserPermissionsServiceFactory = ({ + coreStart, + startPlugins, +}) => ({ + canCreateNewDataView: startPlugins.dataViewEditor.userPermissions.editDataView(), + canAccessFleet: coreStart.application.capabilities.navLinks.integrations, +}); diff --git a/src/plugins/shared_ux/public/services/platform.ts b/src/plugins/shared_ux/public/services/platform.ts index 52f88a1133c8b..b0ee61583dd8d 100644 --- a/src/plugins/shared_ux/public/services/platform.ts +++ b/src/plugins/shared_ux/public/services/platform.ts @@ -6,18 +6,21 @@ * Side Public License, v 1. */ +import { SharedUxPlatformService } from '@kbn/shared-ux-services'; +import { SharedUXPluginStartDeps } from '../types'; +import { KibanaPluginServiceFactory } from './types'; + +/** + * A factory function for creating a Kibana-based implementation of `SharedUXPlatformService`. + */ +export type PlatformServiceFactory = KibanaPluginServiceFactory< + SharedUxPlatformService, + SharedUXPluginStartDeps +>; + /** - * A services providing methods to interact with the Platform in which this plugin is - * running, (almost always Kibana). - * - * Rather than provide the entire `CoreStart` contract to components, we provide simplified - * abstractions around a use case specific to Shared UX. This way, we know exactly how the - * `CoreStart` and other plugins are used, like specifically which methods. This makes - * mocking and refactoring easier when upstream dependencies change. + * A factory function for creating a Kibana-based implementation of `SharedUXPlatformService`. */ -export interface SharedUXPlatformService { - /** - * Sets the fullscreen state of the chrome. - */ - setIsFullscreen: (isFullscreen: boolean) => void; -} +export const platformServiceFactory: PlatformServiceFactory = ({ coreStart }) => ({ + setIsFullscreen: (isVisible: boolean) => coreStart.chrome.setIsVisible(isVisible), +}); diff --git a/src/plugins/shared_ux/public/services/storybook/doc_links.ts b/src/plugins/shared_ux/public/services/storybook/doc_links.ts deleted file mode 100644 index 548d504336108..0000000000000 --- a/src/plugins/shared_ux/public/services/storybook/doc_links.ts +++ /dev/null @@ -1,19 +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 { PluginServiceFactory } from '../types'; -import { SharedUXDocLinksService } from '../doc_links'; - -export type SharedUXDockLinksServiceFactory = PluginServiceFactory; - -/** - * A factory function for creating a Jest-based implementation of `SharedUXDocLinksService`. - */ -export const docLinksServiceFactory: SharedUXDockLinksServiceFactory = () => ({ - dataViewsDocsLink: 'https://www.elastic.co/guide/en/kibana/master/data-views.html', -}); diff --git a/src/plugins/shared_ux/public/services/storybook/editors.ts b/src/plugins/shared_ux/public/services/storybook/editors.ts deleted file mode 100644 index 248699d5beb95..0000000000000 --- a/src/plugins/shared_ux/public/services/storybook/editors.ts +++ /dev/null @@ -1,22 +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 { action } from '@storybook/addon-actions'; -import { PluginServiceFactory } from '../types'; -import { SharedUxDataViewEditorProps, SharedUXEditorsService } from '../editors'; - -export type SharedUXEditorsServiceFactory = PluginServiceFactory; - -/** - * A factory function for creating a storybook implementation of `SharedUXEditorsService`. - */ -export const editorsServiceFactory: SharedUXEditorsServiceFactory = () => ({ - openDataViewEditor: action('openEditor') as SharedUXEditorsService['openDataViewEditor'] as ( - options: SharedUxDataViewEditorProps - ) => () => void, -}); diff --git a/src/plugins/shared_ux/public/services/storybook/permissions.ts b/src/plugins/shared_ux/public/services/storybook/permissions.ts deleted file mode 100644 index 299e06f31f123..0000000000000 --- a/src/plugins/shared_ux/public/services/storybook/permissions.ts +++ /dev/null @@ -1,21 +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 { PluginServiceFactory } from '../types'; -import { SharedUXUserPermissionsService } from '../permissions'; - -export type SharedUXUserPermissionsServiceFactory = - PluginServiceFactory; - -/** - * A factory function for creating a storybook implementation of `SharedUXUserPermissionsService`. - */ -export const userPermissionsServiceFactory: SharedUXUserPermissionsServiceFactory = () => ({ - canCreateNewDataView: true, - canAccessFleet: true, -}); diff --git a/src/plugins/shared_ux/public/services/types.ts b/src/plugins/shared_ux/public/services/types.ts index 2645d5303a33b..15191a493d378 100644 --- a/src/plugins/shared_ux/public/services/types.ts +++ b/src/plugins/shared_ux/public/services/types.ts @@ -9,15 +9,6 @@ import { BehaviorSubject } from 'rxjs'; import { CoreStart, AppUpdater, PluginInitializerContext } from 'src/core/public'; -/** - * A factory function for creating one or more services. - * - * The `S` generic determines the shape of the API being produced. - * The `Parameters` generic determines what parameters are expected to - * create the service. - */ -export type PluginServiceFactory = (params: Parameters) => S; - /** * Parameters necessary to create a Kibana-based service, (e.g. during Plugin * startup or setup). diff --git a/src/plugins/shared_ux/tsconfig.json b/src/plugins/shared_ux/tsconfig.json index 069fe1d069b4a..9e9844d985987 100644 --- a/src/plugins/shared_ux/tsconfig.json +++ b/src/plugins/shared_ux/tsconfig.json @@ -10,7 +10,6 @@ "common/**/*", "public/**/*", "server/**/*", - ".storybook/**/*", "../../../typings/**/*" ], "references": [ @@ -19,9 +18,6 @@ }, { "path": "../data_view_editor/tsconfig.json" - }, - { - "path": "../data_views/tsconfig.json" } ] } diff --git a/test/functional/apps/dashboard/dashboard_filter_bar.ts b/test/functional/apps/dashboard/dashboard_filter_bar.ts index a56143fa8b05e..3f74c4bc2f0dc 100644 --- a/test/functional/apps/dashboard/dashboard_filter_bar.ts +++ b/test/functional/apps/dashboard/dashboard_filter_bar.ts @@ -202,10 +202,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { } else { const documentCell = await dataGrid.getCellElement(1, 3); await documentCell.click(); - const expandCellContentButton = await documentCell.findByTestSubject( - 'euiDataGridCellExpandButton' - ); - await expandCellContentButton.click(); await testSubjects.click('filterForButton'); } const filterCount = await filterBar.getFilterCount(); diff --git a/test/interpreter_functional/test_suites/run_pipeline/esaggs_histogram.ts b/test/interpreter_functional/test_suites/run_pipeline/esaggs_histogram.ts new file mode 100644 index 0000000000000..9b547224cdd44 --- /dev/null +++ b/test/interpreter_functional/test_suites/run_pipeline/esaggs_histogram.ts @@ -0,0 +1,59 @@ +/* + * 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 expect from '@kbn/expect'; +import { ExpectExpression, expectExpressionProvider } from './helpers'; +import { FtrProviderContext } from '../../../functional/ftr_provider_context'; + +export default function ({ + getService, + updateBaselines, +}: FtrProviderContext & { updateBaselines: boolean }) { + let expectExpression: ExpectExpression; + + describe('esaggs number histogram tests', () => { + before(() => { + expectExpression = expectExpressionProvider({ getService, updateBaselines }); + }); + + const timeRange = { + from: '2015-09-21T00:00:00Z', + to: '2015-09-22T00:00:00Z', + }; + + it('auto-extends bounds to total range', async () => { + const expression = ` + kibana_context timeRange={timerange from='${timeRange.from}' to='${timeRange.to}'} + | esaggs index={indexPatternLoad id='logstash-*'} + aggs={aggTerms id="0" enabled=true schema="bucket" field="extension.raw" size=3} + aggs={aggHistogram id="1" enabled=true schema="bucket" field="bytes" interval=5000 autoExtendBounds=true min_doc_count=true} + aggs={aggCount id="2" enabled=true schema="metric"} + `; + const result = await expectExpression( + 'esaggs_histogram_auto_extend', + expression + ).getResponse(); + expect(result.rows).to.eql([ + { 'col-0-0': 'jpg', 'col-1-1': 0, 'col-2-2': 1251 }, + { 'col-0-0': 'jpg', 'col-1-1': 5000, 'col-2-2': 1759 }, + // filling in empty buckets even though the histogram wouldn't extend to those + { 'col-0-0': 'jpg', 'col-1-1': 10000, 'col-2-2': 0 }, + { 'col-0-0': 'jpg', 'col-1-1': 15000, 'col-2-2': 0 }, + { 'col-0-0': 'css', 'col-1-1': 0, 'col-2-2': 294 }, + { 'col-0-0': 'css', 'col-1-1': 5000, 'col-2-2': 402 }, + // filling in empty buckets even though the histogram wouldn't extend to those + { 'col-0-0': 'css', 'col-1-1': 10000, 'col-2-2': 0 }, + { 'col-0-0': 'css', 'col-1-1': 15000, 'col-2-2': 0 }, + { 'col-0-0': 'png', 'col-1-1': 0, 'col-2-2': 90 }, + { 'col-0-0': 'png', 'col-1-1': 5000, 'col-2-2': 128 }, + { 'col-0-0': 'png', 'col-1-1': 10000, 'col-2-2': 126 }, + { 'col-0-0': 'png', 'col-1-1': 15000, 'col-2-2': 112 }, + ]); + }); + }); +} diff --git a/test/interpreter_functional/test_suites/run_pipeline/index.ts b/test/interpreter_functional/test_suites/run_pipeline/index.ts index e24563a5918eb..8cb45a08be220 100644 --- a/test/interpreter_functional/test_suites/run_pipeline/index.ts +++ b/test/interpreter_functional/test_suites/run_pipeline/index.ts @@ -49,5 +49,6 @@ export default function ({ getService, getPageObjects, loadTestFile }: FtrProvid loadTestFile(require.resolve('./esaggs_significanttext')); loadTestFile(require.resolve('./esaggs_rareterms')); loadTestFile(require.resolve('./esaggs_topmetrics')); + loadTestFile(require.resolve('./esaggs_histogram')); }); } diff --git a/x-pack/examples/third_party_vis_lens_example/public/visualization.tsx b/x-pack/examples/third_party_vis_lens_example/public/visualization.tsx index e7a6c60ad5b2e..a1796eee9b253 100644 --- a/x-pack/examples/third_party_vis_lens_example/public/visualization.tsx +++ b/x-pack/examples/third_party_vis_lens_example/public/visualization.tsx @@ -75,7 +75,7 @@ export const getRotatingNumberVisualization = ({ }, getSuggestions: ({ state, table }) => { - if (table.columns.length > 1) { + if (!table.columns.length || table.columns.length > 1) { return []; } if (state && table.changeType === 'unchanged') { diff --git a/x-pack/plugins/alerting/server/rules_client/lib/mapped_params_utils.test.ts b/x-pack/plugins/alerting/server/rules_client/lib/mapped_params_utils.test.ts index d8618d0ed6c21..705fc1b05ede3 100644 --- a/x-pack/plugins/alerting/server/rules_client/lib/mapped_params_utils.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/lib/mapped_params_utils.test.ts @@ -128,4 +128,23 @@ describe('modifyFilterKueryNode', () => { value: '40-medium', }); }); + + it('do NOT modify the resulting kuery node AST filter for alert params when they are not part of mapped params', () => { + // Make sure it works for both camel and snake case params + const astFilter = fromKueryExpression( + 'alert.attributes.name: "Rule I" and alert.attributes.tags: "fast" and alert.attributes.params.threat.tactic.name: Exfiltration' + ); + + modifyFilterKueryNode({ astFilter }); + + expect(astFilter.arguments[2].arguments[0]).toEqual({ + type: 'literal', + value: 'alert.attributes.params.threat.tactic.name', + }); + + expect(astFilter.arguments[2].arguments[1]).toEqual({ + type: 'literal', + value: 'Exfiltration', + }); + }); }); diff --git a/x-pack/plugins/alerting/server/rules_client/lib/mapped_params_utils.ts b/x-pack/plugins/alerting/server/rules_client/lib/mapped_params_utils.ts index b4d82990654c2..e9624d4604c46 100644 --- a/x-pack/plugins/alerting/server/rules_client/lib/mapped_params_utils.ts +++ b/x-pack/plugins/alerting/server/rules_client/lib/mapped_params_utils.ts @@ -145,7 +145,16 @@ export const modifyFilterKueryNode = ({ const firstAttribute = getFieldNameAttribute(fieldName, ['alert', 'attributes']); // Replace the ast.value for params to mapped_params if (firstAttribute === 'params') { - ast.value = getModifiedFilter(ast.value); + const attributeAfterParams = getFieldNameAttribute(fieldName, [ + 'alert', + 'attributes', + 'params', + ]); + if ( + MAPPED_PARAMS_PROPERTIES.includes(attributeAfterParams as keyof MappedParamsProperties) + ) { + ast.value = getModifiedFilter(ast.value); + } } } @@ -155,8 +164,16 @@ export const modifyFilterKueryNode = ({ // Replace the ast.value for params value to the modified mapped_params value if (firstAttribute === 'params' && ast.value) { - const attribute = getFieldNameAttribute(localFieldName, ['alert', 'attributes', 'params']); - ast.value = getModifiedValue(attribute, ast.value); + const attributeAfterParams = getFieldNameAttribute(localFieldName, [ + 'alert', + 'attributes', + 'params', + ]); + if ( + MAPPED_PARAMS_PROPERTIES.includes(attributeAfterParams as keyof MappedParamsProperties) + ) { + ast.value = getModifiedValue(attributeAfterParams, ast.value); + } } } }; diff --git a/x-pack/plugins/apm/public/components/app/service_overview/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/index.tsx index 3c2db54088770..078b797b84ae8 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/index.tsx @@ -128,7 +128,7 @@ export function ServiceOverview() { isSingleColumn={isSingleColumn} start={start} end={end} - hidePerPageOptions={true} + showPerPageOptions={false} /> @@ -185,7 +185,7 @@ export function ServiceOverview() { {i18n.translate( diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_dependencies_table/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_dependencies_table/index.tsx index 88498f4186457..335578cd88e10 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_dependencies_table/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_dependencies_table/index.tsx @@ -23,14 +23,14 @@ interface ServiceOverviewDependenciesTableProps { fixedHeight?: boolean; isSingleColumn?: boolean; link?: ReactNode; - hidePerPageOptions?: boolean; + showPerPageOptions?: boolean; } export function ServiceOverviewDependenciesTable({ fixedHeight, isSingleColumn = true, link, - hidePerPageOptions = false, + showPerPageOptions = true, }: ServiceOverviewDependenciesTableProps) { const { query: { @@ -148,7 +148,7 @@ export function ServiceOverviewDependenciesTable({ )} status={status} link={link} - hidePerPageOptions={hidePerPageOptions} + showPerPageOptions={showPerPageOptions} /> ); } diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx index 8eb5158f304c5..edf75cbb27f8b 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx @@ -243,7 +243,7 @@ export function ServiceOverviewErrorsTable({ serviceName }: Props) { pageSize: PAGE_SIZE, totalItemCount: totalItems, pageSizeOptions: [PAGE_SIZE], - hidePerPageOptions: true, + showPerPageOptions: false, }} loading={status === FETCH_STATUS.LOADING} onChange={(newTableOptions: { diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/index.tsx index 03f036e44b4c1..c12b0a19644f5 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/index.tsx @@ -137,7 +137,7 @@ export function ServiceOverviewInstancesTable({ pageIndex, pageSize: PAGE_SIZE, totalItemCount: mainStatsItemCount, - hidePerPageOptions: true, + showPerPageOptions: false, }; return ( diff --git a/x-pack/plugins/apm/public/components/app/service_profiling/service_profiling_flamegraph.tsx b/x-pack/plugins/apm/public/components/app/service_profiling/service_profiling_flamegraph.tsx index e0c2483b70f88..e1739d3ba8b91 100644 --- a/x-pack/plugins/apm/public/components/app/service_profiling/service_profiling_flamegraph.tsx +++ b/x-pack/plugins/apm/public/components/app/service_profiling/service_profiling_flamegraph.tsx @@ -387,7 +387,7 @@ export function ServiceProfilingFlamegraph({ }} pagination={{ pageSize: 20, - hidePerPageOptions: true, + showPerPageOptions: false, }} compressed columns={[ diff --git a/x-pack/plugins/apm/public/components/fleet_integration/apm_agents/agent_instructions_mappings.ts b/x-pack/plugins/apm/public/components/fleet_integration/apm_agents/agent_instructions_mappings.ts index 8a0f4fa801687..93260f09d7f6b 100644 --- a/x-pack/plugins/apm/public/components/fleet_integration/apm_agents/agent_instructions_mappings.ts +++ b/x-pack/plugins/apm/public/components/fleet_integration/apm_agents/agent_instructions_mappings.ts @@ -20,7 +20,7 @@ import { } from '../../../../common/tutorial/instructions/apm_agent_instructions'; import { AgentName } from '../../../../typings/es_schemas/ui/fields/agent'; // TODO: Uncomment once https://github.com/elastic/beats/issues/29631 has been closed -// import { JavaRuntimeAttachment } from './runtime_attachment/supported_agents/java_runtime_attachment'; +import { JavaRuntimeAttachment } from './runtime_attachment/supported_agents/java_runtime_attachment'; import { NewPackagePolicy, PackagePolicy, @@ -56,8 +56,7 @@ export const ApmAgentInstructionsMappings: Array<{ title: 'Java', variantId: 'java', createAgentInstructions: createJavaAgentInstructions, - // TODO: Uncomment once https://github.com/elastic/beats/issues/29631 has been closed - // AgentRuntimeAttachment: JavaRuntimeAttachment, + AgentRuntimeAttachment: JavaRuntimeAttachment, }, { agentName: 'rum-js', diff --git a/x-pack/plugins/apm/public/components/shared/dependencies_table/index.tsx b/x-pack/plugins/apm/public/components/shared/dependencies_table/index.tsx index 2d68cb5e9dae7..8cefe76771886 100644 --- a/x-pack/plugins/apm/public/components/shared/dependencies_table/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/dependencies_table/index.tsx @@ -49,7 +49,7 @@ interface Props { nameColumnTitle: React.ReactNode; status: FETCH_STATUS; compact?: boolean; - hidePerPageOptions?: boolean; + showPerPageOptions?: boolean; } export function DependenciesTable(props: Props) { @@ -62,7 +62,7 @@ export function DependenciesTable(props: Props) { nameColumnTitle, status, compact = true, - hidePerPageOptions = false, + showPerPageOptions = true, } = props; // SparkPlots should be hidden if we're in two-column view and size XL (1200px) @@ -236,7 +236,7 @@ export function DependenciesTable(props: Props) { initialSortField="impactValue" initialSortDirection="desc" pagination={true} - hidePerPageOptions={hidePerPageOptions} + showPerPageOptions={showPerPageOptions} /> diff --git a/x-pack/plugins/apm/public/components/shared/managed_table/__snapshots__/managed_table.test.tsx.snap b/x-pack/plugins/apm/public/components/shared/managed_table/__snapshots__/managed_table.test.tsx.snap index 3559ee4afbb82..e8699e7c682cd 100644 --- a/x-pack/plugins/apm/public/components/shared/managed_table/__snapshots__/managed_table.test.tsx.snap +++ b/x-pack/plugins/apm/public/components/shared/managed_table/__snapshots__/managed_table.test.tsx.snap @@ -44,7 +44,6 @@ exports[`ManagedTable should render a page-full of items, with defaults 1`] = ` onChange={[Function]} pagination={ Object { - "hidePerPageOptions": false, "pageIndex": 0, "pageSize": 25, "pageSizeOptions": Array [ @@ -52,6 +51,7 @@ exports[`ManagedTable should render a page-full of items, with defaults 1`] = ` 25, 50, ], + "showPerPageOptions": true, "totalItemCount": 3, } } @@ -104,7 +104,6 @@ exports[`ManagedTable should render when specifying initial values 1`] = ` onChange={[Function]} pagination={ Object { - "hidePerPageOptions": false, "pageIndex": 1, "pageSize": 2, "pageSizeOptions": Array [ @@ -112,6 +111,7 @@ exports[`ManagedTable should render when specifying initial values 1`] = ` 25, 50, ], + "showPerPageOptions": false, "totalItemCount": 3, } } diff --git a/x-pack/plugins/apm/public/components/shared/managed_table/index.tsx b/x-pack/plugins/apm/public/components/shared/managed_table/index.tsx index 37d55887cd182..f8f68e08650bf 100644 --- a/x-pack/plugins/apm/public/components/shared/managed_table/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/managed_table/index.tsx @@ -33,7 +33,7 @@ interface Props { initialPageSize?: number; initialSortField?: ITableColumn['field']; initialSortDirection?: 'asc' | 'desc'; - hidePerPageOptions?: boolean; + showPerPageOptions?: boolean; noItemsMessage?: React.ReactNode; sortItems?: boolean; sortFn?: ( @@ -67,7 +67,7 @@ function UnoptimizedManagedTable(props: Props) { initialPageSize = INITIAL_PAGE_SIZE, initialSortField = props.columns[0]?.field || '', initialSortDirection = 'asc', - hidePerPageOptions = false, + showPerPageOptions = true, noItemsMessage, sortItems = true, sortFn = defaultSortFn, @@ -127,13 +127,13 @@ function UnoptimizedManagedTable(props: Props) { return; } return { - hidePerPageOptions, + showPerPageOptions, totalItemCount: items.length, pageIndex: page, pageSize, pageSizeOptions: PAGE_SIZE_OPTIONS, }; - }, [hidePerPageOptions, items, page, pageSize, pagination]); + }, [showPerPageOptions, items, page, pageSize, pagination]); const showNoItemsMessage = useMemo(() => { return isLoading diff --git a/x-pack/plugins/apm/public/components/shared/managed_table/managed_table.test.tsx b/x-pack/plugins/apm/public/components/shared/managed_table/managed_table.test.tsx index c474d98a3f0d4..10f3ba29733dc 100644 --- a/x-pack/plugins/apm/public/components/shared/managed_table/managed_table.test.tsx +++ b/x-pack/plugins/apm/public/components/shared/managed_table/managed_table.test.tsx @@ -48,7 +48,7 @@ describe('ManagedTable', () => { initialSortDirection="desc" initialPageIndex={1} initialPageSize={2} - hidePerPageOptions={false} + showPerPageOptions={false} /> ) ).toMatchSnapshot(); diff --git a/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx b/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx index bf6e2b70d390e..6134f9c3cdcb1 100644 --- a/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx @@ -57,7 +57,7 @@ interface Props { hideViewTransactionsLink?: boolean; isSingleColumn?: boolean; numberOfTransactionsPerPage?: number; - hidePerPageOptions?: boolean; + showPerPageOptions?: boolean; showAggregationAccurateCallout?: boolean; environment: string; fixedHeight?: boolean; @@ -71,7 +71,7 @@ export function TransactionsTable({ hideViewTransactionsLink = false, isSingleColumn = true, numberOfTransactionsPerPage = 5, - hidePerPageOptions = false, + showPerPageOptions = true, showAggregationAccurateCallout = false, environment, kuery, @@ -329,7 +329,7 @@ export function TransactionsTable({ defaultMessage: 'No transaction groups found', }) } - hidePerPageOptions={hidePerPageOptions} + showPerPageOptions={showPerPageOptions} /> diff --git a/x-pack/plugins/canvas/public/components/asset_manager/__stories__/__snapshots__/asset.stories.storyshot b/x-pack/plugins/canvas/public/components/asset_manager/__stories__/__snapshots__/asset.stories.storyshot index a891b7ebe7686..6db24bd0b984c 100644 --- a/x-pack/plugins/canvas/public/components/asset_manager/__stories__/__snapshots__/asset.stories.storyshot +++ b/x-pack/plugins/canvas/public/components/asset_manager/__stories__/__snapshots__/asset.stories.storyshot @@ -70,7 +70,6 @@ exports[`Storyshots components/Assets/Asset airplane 1`] = `