diff --git a/.ci/Jenkinsfile_visual_baseline b/.ci/Jenkinsfile_visual_baseline index 2a16c499fa168..7c7cc8d98c306 100644 --- a/.ci/Jenkinsfile_visual_baseline +++ b/.ci/Jenkinsfile_visual_baseline @@ -21,5 +21,6 @@ kibanaPipeline(timeoutMinutes: 120) { } kibanaPipeline.sendMail() + slackNotifications.onFailure() } } diff --git a/.ci/packer_cache_for_branch.sh b/.ci/packer_cache_for_branch.sh index a9fbe781915b6..5b4a94be50fa2 100755 --- a/.ci/packer_cache_for_branch.sh +++ b/.ci/packer_cache_for_branch.sh @@ -46,7 +46,7 @@ echo "Creating bootstrap_cache archive" # archive cacheable directories mkdir -p "$HOME/.kibana/bootstrap_cache" tar -cf "$HOME/.kibana/bootstrap_cache/$branch.tar" \ - x-pack/plugins/reporting/.chromium \ + .chromium \ .es \ .chromedriver \ .geckodriver; diff --git a/.eslintignore b/.eslintignore index 9de2cc2872960..4b5e781c26971 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,6 +1,7 @@ **/*.js.snap **/graphql/types.ts /.es +/.chromium /build /built_assets /config/apm.dev.js diff --git a/.eslintrc.js b/.eslintrc.js index 8d979dc0f8645..4425ad3a12659 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -906,6 +906,18 @@ module.exports = { }, }, + /** + * Enterprise Search overrides + */ + { + files: ['x-pack/plugins/enterprise_search/**/*.{ts,tsx}'], + excludedFiles: ['x-pack/plugins/enterprise_search/**/*.{test,mock}.{ts,tsx}'], + rules: { + 'react-hooks/exhaustive-deps': 'off', + '@typescript-eslint/no-explicit-any': 'error', + }, + }, + /** * disable jsx-a11y for kbn-ui-framework */ diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4aab9943022d4..f053c6da9c29b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -201,6 +201,11 @@ x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @elastic/kib # Design **/*.scss @elastic/kibana-design +# Enterprise Search +/x-pack/plugins/enterprise_search/ @elastic/app-search-frontend @elastic/workplace-search-frontend +/x-pack/test/functional_enterprise_search/ @elastic/app-search-frontend @elastic/workplace-search-frontend +/x-pack/plugins/enterprise_search/**/*.scss @elastic/ent-search-design + # Elasticsearch UI /src/plugins/dev_tools/ @elastic/es-ui /src/plugins/console/ @elastic/es-ui diff --git a/.gitignore b/.gitignore index 32377ec0f1ffe..716cea937f9c0 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .signing-config.json .ackrc /.es +/.chromium .DS_Store .node_binaries .native_modules diff --git a/docs/apm/api.asciidoc b/docs/apm/api.asciidoc index f6bc83d4086c2..97fdcd3e13de9 100644 --- a/docs/apm/api.asciidoc +++ b/docs/apm/api.asciidoc @@ -398,7 +398,7 @@ include::api.asciidoc[tag=using-the-APIs] [%collapsible%open] ====== `version` ::: - (required, string) Name of service. + (required, string) Version of service. `environment` ::: (optional, string) Environment of service. diff --git a/docs/images/canvas-add-image.gif b/docs/canvas/images/canvas-add-image.gif similarity index 100% rename from docs/images/canvas-add-image.gif rename to docs/canvas/images/canvas-add-image.gif diff --git a/docs/images/canvas-add-pages.gif b/docs/canvas/images/canvas-add-pages.gif similarity index 100% rename from docs/images/canvas-add-pages.gif rename to docs/canvas/images/canvas-add-pages.gif diff --git a/docs/images/canvas-autoplay-interval.png b/docs/canvas/images/canvas-autoplay-interval.png similarity index 100% rename from docs/images/canvas-autoplay-interval.png rename to docs/canvas/images/canvas-autoplay-interval.png diff --git a/docs/images/canvas-background-color-picker.png b/docs/canvas/images/canvas-background-color-picker.png similarity index 100% rename from docs/images/canvas-background-color-picker.png rename to docs/canvas/images/canvas-background-color-picker.png diff --git a/docs/images/canvas-change-your-expression-chart-no-legend.png b/docs/canvas/images/canvas-change-your-expression-chart-no-legend.png similarity index 100% rename from docs/images/canvas-change-your-expression-chart-no-legend.png rename to docs/canvas/images/canvas-change-your-expression-chart-no-legend.png diff --git a/docs/images/canvas-change-your-expression-chart.png b/docs/canvas/images/canvas-change-your-expression-chart.png similarity index 100% rename from docs/images/canvas-change-your-expression-chart.png rename to docs/canvas/images/canvas-change-your-expression-chart.png diff --git a/docs/images/canvas-chart-element.png b/docs/canvas/images/canvas-chart-element.png similarity index 100% rename from docs/images/canvas-chart-element.png rename to docs/canvas/images/canvas-chart-element.png diff --git a/docs/images/canvas-create-URL.gif b/docs/canvas/images/canvas-create-URL.gif similarity index 100% rename from docs/images/canvas-create-URL.gif rename to docs/canvas/images/canvas-create-URL.gif diff --git a/docs/images/canvas-element-select.gif b/docs/canvas/images/canvas-element-select.gif similarity index 100% rename from docs/images/canvas-element-select.gif rename to docs/canvas/images/canvas-element-select.gif diff --git a/docs/images/canvas-export-workpad.png b/docs/canvas/images/canvas-export-workpad.png similarity index 100% rename from docs/images/canvas-export-workpad.png rename to docs/canvas/images/canvas-export-workpad.png diff --git a/docs/images/canvas-fullscreen.png b/docs/canvas/images/canvas-fullscreen.png similarity index 100% rename from docs/images/canvas-fullscreen.png rename to docs/canvas/images/canvas-fullscreen.png diff --git a/docs/images/canvas-functions-can-take-arguments-donut-chart.png b/docs/canvas/images/canvas-functions-can-take-arguments-donut-chart.png similarity index 100% rename from docs/images/canvas-functions-can-take-arguments-donut-chart.png rename to docs/canvas/images/canvas-functions-can-take-arguments-donut-chart.png diff --git a/docs/images/canvas-functions-can-take-arguments-pie-chart.png b/docs/canvas/images/canvas-functions-can-take-arguments-pie-chart.png similarity index 100% rename from docs/images/canvas-functions-can-take-arguments-pie-chart.png rename to docs/canvas/images/canvas-functions-can-take-arguments-pie-chart.png diff --git a/docs/images/canvas-generate-pdf.gif b/docs/canvas/images/canvas-generate-pdf.gif similarity index 100% rename from docs/images/canvas-generate-pdf.gif rename to docs/canvas/images/canvas-generate-pdf.gif diff --git a/docs/images/canvas-gs-example.png b/docs/canvas/images/canvas-gs-example.png similarity index 100% rename from docs/images/canvas-gs-example.png rename to docs/canvas/images/canvas-gs-example.png diff --git a/docs/images/canvas-image-element.png b/docs/canvas/images/canvas-image-element.png similarity index 100% rename from docs/images/canvas-image-element.png rename to docs/canvas/images/canvas-image-element.png diff --git a/docs/images/canvas-map-embed.gif b/docs/canvas/images/canvas-map-embed.gif similarity index 100% rename from docs/images/canvas-map-embed.gif rename to docs/canvas/images/canvas-map-embed.gif diff --git a/docs/images/canvas-metric-element.png b/docs/canvas/images/canvas-metric-element.png similarity index 100% rename from docs/images/canvas-metric-element.png rename to docs/canvas/images/canvas-metric-element.png diff --git a/docs/images/canvas-refresh-interval.png b/docs/canvas/images/canvas-refresh-interval.png similarity index 100% rename from docs/images/canvas-refresh-interval.png rename to docs/canvas/images/canvas-refresh-interval.png diff --git a/docs/images/canvas-timefilter-element.png b/docs/canvas/images/canvas-timefilter-element.png similarity index 100% rename from docs/images/canvas-timefilter-element.png rename to docs/canvas/images/canvas-timefilter-element.png diff --git a/docs/images/canvas-zoom-controls.png b/docs/canvas/images/canvas-zoom-controls.png similarity index 100% rename from docs/images/canvas-zoom-controls.png rename to docs/canvas/images/canvas-zoom-controls.png diff --git a/docs/images/canvas_element_options.png b/docs/canvas/images/canvas_element_options.png similarity index 100% rename from docs/images/canvas_element_options.png rename to docs/canvas/images/canvas_element_options.png diff --git a/docs/images/canvas_save_element.png b/docs/canvas/images/canvas_save_element.png similarity index 100% rename from docs/images/canvas_save_element.png rename to docs/canvas/images/canvas_save_element.png diff --git a/docs/images/settings.png b/docs/dev-tools/console/images/settings.png similarity index 100% rename from docs/images/settings.png rename to docs/dev-tools/console/images/settings.png diff --git a/docs/images/jenkins/job_view.png b/docs/developer/images/job_view.png similarity index 100% rename from docs/images/jenkins/job_view.png rename to docs/developer/images/job_view.png diff --git a/docs/images/jenkins/pipeline_steps_view.png b/docs/developer/images/pipeline_steps_view.png similarity index 100% rename from docs/images/jenkins/pipeline_steps_view.png rename to docs/developer/images/pipeline_steps_view.png diff --git a/docs/developer/testing/interpreting-ci-failures.asciidoc b/docs/developer/testing/interpreting-ci-failures.asciidoc index bc237928cf5aa..c47a59217d89b 100644 --- a/docs/developer/testing/interpreting-ci-failures.asciidoc +++ b/docs/developer/testing/interpreting-ci-failures.asciidoc @@ -17,7 +17,7 @@ Clicking the link next to the check in the conversation tab of a pull request wi To view the results of a job execution in Jenkins, either click the link in the comment left by `@elasticmachine` or search for the `kibana-ci` check in the list at the bottom of the PR. This link will take you to the top-level page for the specific job execution that failed. -image::images/jenkins/job_view.png[] +image::images/job_view.png[] 1. *Git Changes:* the list of commits that were in this build which weren't in the previous build. For Pull Requests this list is calculated by comparing against the most recent Pull Request which was tested, it is not limited to build for this specific Pull Request, so it's not very useful. 2. *Test Results:* A link to the test results screen, and shortcuts to the failed tests. Functional tests capture and store the log output from each specific test, and make it visible at these links. For other test runners only the error message is visible and log output must be tracked down in the *Pipeline Steps*. @@ -29,6 +29,6 @@ image::images/jenkins/job_view.png[] To view the logs for a failed specific ciGroup, jest, mocha, type checkers, linters, etc., click on the *Pipeline Steps* link in from the Job page. -image::images/jenkins/pipeline_steps_view.png[] +image::images/pipeline_steps_view.png[] Scroll down the page until you find a failed step *(1)*, and then look up a few lines for the `Branch:` step to see which specific job this is. If this is the job you're looking for click the little terminal icon next to the failed step *(1)* to view the logs for that specific step in the Pipeline. \ No newline at end of file diff --git a/docs/development/core/server/kibana-plugin-core-server.discoveredplugin.md b/docs/development/core/server/kibana-plugin-core-server.discoveredplugin.md index 0e2b9bd60ab67..b88a179c5c4b3 100644 --- a/docs/development/core/server/kibana-plugin-core-server.discoveredplugin.md +++ b/docs/development/core/server/kibana-plugin-core-server.discoveredplugin.md @@ -19,5 +19,6 @@ export interface DiscoveredPlugin | [configPath](./kibana-plugin-core-server.discoveredplugin.configpath.md) | ConfigPath | Root configuration path used by the plugin, defaults to "id" in snake\_case format. | | [id](./kibana-plugin-core-server.discoveredplugin.id.md) | PluginName | Identifier of the plugin. | | [optionalPlugins](./kibana-plugin-core-server.discoveredplugin.optionalplugins.md) | readonly PluginName[] | An optional list of the other plugins that if installed and enabled \*\*may be\*\* leveraged by this plugin for some additional functionality but otherwise are not required for this plugin to work properly. | +| [requiredBundles](./kibana-plugin-core-server.discoveredplugin.requiredbundles.md) | readonly PluginName[] | List of plugin ids that this plugin's UI code imports modules from that are not in requiredPlugins. | | [requiredPlugins](./kibana-plugin-core-server.discoveredplugin.requiredplugins.md) | readonly PluginName[] | An optional list of the other plugins that \*\*must be\*\* installed and enabled for this plugin to function properly. | diff --git a/docs/development/core/server/kibana-plugin-core-server.discoveredplugin.requiredbundles.md b/docs/development/core/server/kibana-plugin-core-server.discoveredplugin.requiredbundles.md new file mode 100644 index 0000000000000..6d54adb5236ea --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.discoveredplugin.requiredbundles.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [DiscoveredPlugin](./kibana-plugin-core-server.discoveredplugin.md) > [requiredBundles](./kibana-plugin-core-server.discoveredplugin.requiredbundles.md) + +## DiscoveredPlugin.requiredBundles property + +List of plugin ids that this plugin's UI code imports modules from that are not in `requiredPlugins`. + +Signature: + +```typescript +readonly requiredBundles: readonly PluginName[]; +``` + +## Remarks + +The plugins listed here will be loaded in the browser, even if the plugin is disabled. Required by `@kbn/optimizer` to support cross-plugin imports. "core" and plugins already listed in `requiredPlugins` do not need to be duplicated here. + diff --git a/docs/development/core/server/kibana-plugin-core-server.md b/docs/development/core/server/kibana-plugin-core-server.md index 7ebd0531619fd..8d4c0c915437e 100644 --- a/docs/development/core/server/kibana-plugin-core-server.md +++ b/docs/development/core/server/kibana-plugin-core-server.md @@ -154,7 +154,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [SavedObjectsBulkUpdateResponse](./kibana-plugin-core-server.savedobjectsbulkupdateresponse.md) | | | [SavedObjectsClientProviderOptions](./kibana-plugin-core-server.savedobjectsclientprovideroptions.md) | Options to control the creation of the Saved Objects Client. | | [SavedObjectsClientWrapperOptions](./kibana-plugin-core-server.savedobjectsclientwrapperoptions.md) | Options passed to each SavedObjectsClientWrapperFactory to aid in creating the wrapper instance. | -| [SavedObjectsComplexFieldMapping](./kibana-plugin-core-server.savedobjectscomplexfieldmapping.md) | See [SavedObjectsFieldMapping](./kibana-plugin-core-server.savedobjectsfieldmapping.md) for documentation.Note: this type intentially doesn't include a type definition for defining the dynamic mapping parameter. Saved Object fields should always inherit the dynamic: 'strict' paramater. If you are unsure of the shape of your data use type: 'object', enabled: false instead. | +| [SavedObjectsComplexFieldMapping](./kibana-plugin-core-server.savedobjectscomplexfieldmapping.md) | See [SavedObjectsFieldMapping](./kibana-plugin-core-server.savedobjectsfieldmapping.md) for documentation. | | [SavedObjectsCoreFieldMapping](./kibana-plugin-core-server.savedobjectscorefieldmapping.md) | See [SavedObjectsFieldMapping](./kibana-plugin-core-server.savedobjectsfieldmapping.md) for documentation. | | [SavedObjectsCreateOptions](./kibana-plugin-core-server.savedobjectscreateoptions.md) | | | [SavedObjectsDeleteByNamespaceOptions](./kibana-plugin-core-server.savedobjectsdeletebynamespaceoptions.md) | | diff --git a/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.md b/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.md index 5edee51d6c523..6db2f89590149 100644 --- a/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.md +++ b/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.md @@ -25,6 +25,7 @@ Should never be used in code outside of Core but is exported for documentation p | [id](./kibana-plugin-core-server.pluginmanifest.id.md) | PluginName | Identifier of the plugin. Must be a string in camelCase. Part of a plugin public contract. Other plugins leverage it to access plugin API, navigate to the plugin, etc. | | [kibanaVersion](./kibana-plugin-core-server.pluginmanifest.kibanaversion.md) | string | The version of Kibana the plugin is compatible with, defaults to "version". | | [optionalPlugins](./kibana-plugin-core-server.pluginmanifest.optionalplugins.md) | readonly PluginName[] | An optional list of the other plugins that if installed and enabled \*\*may be\*\* leveraged by this plugin for some additional functionality but otherwise are not required for this plugin to work properly. | +| [requiredBundles](./kibana-plugin-core-server.pluginmanifest.requiredbundles.md) | readonly string[] | List of plugin ids that this plugin's UI code imports modules from that are not in requiredPlugins. | | [requiredPlugins](./kibana-plugin-core-server.pluginmanifest.requiredplugins.md) | readonly PluginName[] | An optional list of the other plugins that \*\*must be\*\* installed and enabled for this plugin to function properly. | | [server](./kibana-plugin-core-server.pluginmanifest.server.md) | boolean | Specifies whether plugin includes some server-side specific functionality. | | [ui](./kibana-plugin-core-server.pluginmanifest.ui.md) | boolean | Specifies whether plugin includes some client/browser specific functionality that should be included into client bundle via public/ui_plugin.js file. | diff --git a/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.requiredbundles.md b/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.requiredbundles.md new file mode 100644 index 0000000000000..98505d07101fe --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.requiredbundles.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [PluginManifest](./kibana-plugin-core-server.pluginmanifest.md) > [requiredBundles](./kibana-plugin-core-server.pluginmanifest.requiredbundles.md) + +## PluginManifest.requiredBundles property + +List of plugin ids that this plugin's UI code imports modules from that are not in `requiredPlugins`. + +Signature: + +```typescript +readonly requiredBundles: readonly string[]; +``` + +## Remarks + +The plugins listed here will be loaded in the browser, even if the plugin is disabled. Required by `@kbn/optimizer` to support cross-plugin imports. "core" and plugins already listed in `requiredPlugins` do not need to be duplicated here. + diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectscomplexfieldmapping.dynamic.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectscomplexfieldmapping.dynamic.md new file mode 100644 index 0000000000000..b01da3c62fda6 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectscomplexfieldmapping.dynamic.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [SavedObjectsComplexFieldMapping](./kibana-plugin-core-server.savedobjectscomplexfieldmapping.md) > [dynamic](./kibana-plugin-core-server.savedobjectscomplexfieldmapping.dynamic.md) + +## SavedObjectsComplexFieldMapping.dynamic property + +The dynamic property of the mapping, either `false` or `'strict'`. If unspecified `dynamic: 'strict'` will be inherited from the top-level index mappings. + +Note: To limit the number of mapping fields Saved Object types should \*never\* use `dynamic: true`. + +Signature: + +```typescript +dynamic?: false | 'strict'; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectscomplexfieldmapping.enabled.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectscomplexfieldmapping.enabled.md new file mode 100644 index 0000000000000..08513aa2a849b --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectscomplexfieldmapping.enabled.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [SavedObjectsComplexFieldMapping](./kibana-plugin-core-server.savedobjectscomplexfieldmapping.md) > [enabled](./kibana-plugin-core-server.savedobjectscomplexfieldmapping.enabled.md) + +## SavedObjectsComplexFieldMapping.enabled property + +Signature: + +```typescript +enabled?: boolean; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectscomplexfieldmapping.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectscomplexfieldmapping.md index cb81686b424ec..fc262cad54f18 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectscomplexfieldmapping.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectscomplexfieldmapping.md @@ -6,8 +6,6 @@ See [SavedObjectsFieldMapping](./kibana-plugin-core-server.savedobjectsfieldmapping.md) for documentation. -Note: this type intentially doesn't include a type definition for defining the `dynamic` mapping parameter. Saved Object fields should always inherit the `dynamic: 'strict'` paramater. If you are unsure of the shape of your data use `type: 'object', enabled: false` instead. - Signature: ```typescript @@ -19,6 +17,8 @@ export interface SavedObjectsComplexFieldMapping | Property | Type | Description | | --- | --- | --- | | [doc\_values](./kibana-plugin-core-server.savedobjectscomplexfieldmapping.doc_values.md) | boolean | | +| [dynamic](./kibana-plugin-core-server.savedobjectscomplexfieldmapping.dynamic.md) | false | 'strict' | The dynamic property of the mapping, either false or 'strict'. If unspecified dynamic: 'strict' will be inherited from the top-level index mappings.Note: To limit the number of mapping fields Saved Object types should \*never\* use dynamic: true. | +| [enabled](./kibana-plugin-core-server.savedobjectscomplexfieldmapping.enabled.md) | boolean | | | [properties](./kibana-plugin-core-server.savedobjectscomplexfieldmapping.properties.md) | SavedObjectsMappingProperties | | | [type](./kibana-plugin-core-server.savedobjectscomplexfieldmapping.type.md) | string | | diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectscorefieldmapping.enabled.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectscorefieldmapping.enabled.md deleted file mode 100644 index c0b556e99ebc3..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectscorefieldmapping.enabled.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [SavedObjectsCoreFieldMapping](./kibana-plugin-core-server.savedobjectscorefieldmapping.md) > [enabled](./kibana-plugin-core-server.savedobjectscorefieldmapping.enabled.md) - -## SavedObjectsCoreFieldMapping.enabled property - -Signature: - -```typescript -enabled?: boolean; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectscorefieldmapping.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectscorefieldmapping.md index b9e726eac799d..e9b9c2bcf51b5 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectscorefieldmapping.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectscorefieldmapping.md @@ -17,7 +17,6 @@ export interface SavedObjectsCoreFieldMapping | Property | Type | Description | | --- | --- | --- | | [doc\_values](./kibana-plugin-core-server.savedobjectscorefieldmapping.doc_values.md) | boolean | | -| [enabled](./kibana-plugin-core-server.savedobjectscorefieldmapping.enabled.md) | boolean | | | [fields](./kibana-plugin-core-server.savedobjectscorefieldmapping.fields.md) | {
[subfield: string]: {
type: string;
ignore_above?: number;
};
} | | | [index](./kibana-plugin-core-server.savedobjectscorefieldmapping.index.md) | boolean | | | [null\_value](./kibana-plugin-core-server.savedobjectscorefieldmapping.null_value.md) | number | boolean | string | | diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectstypemappingdefinition.dynamic.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectstypemappingdefinition.dynamic.md index 74efa75768f9c..70775760ac77d 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectstypemappingdefinition.dynamic.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectstypemappingdefinition.dynamic.md @@ -4,7 +4,7 @@ ## SavedObjectsTypeMappingDefinition.dynamic property -The dynamic property of the mapping. either `false` or 'strict'. Defaults to `false` +The dynamic property of the mapping, either `false` or `'strict'`. If unspecified `dynamic: 'strict'` will be inherited from the top-level index mappings. Signature: diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectstypemappingdefinition.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectstypemappingdefinition.md index 77ded4389c0a0..3d3b73880fa7f 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectstypemappingdefinition.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectstypemappingdefinition.md @@ -41,6 +41,6 @@ const typeDefinition: SavedObjectsTypeMappingDefinition = { | Property | Type | Description | | --- | --- | --- | -| [dynamic](./kibana-plugin-core-server.savedobjectstypemappingdefinition.dynamic.md) | false | 'strict' | The dynamic property of the mapping. either false or 'strict'. Defaults to false | +| [dynamic](./kibana-plugin-core-server.savedobjectstypemappingdefinition.dynamic.md) | false | 'strict' | The dynamic property of the mapping, either false or 'strict'. If unspecified dynamic: 'strict' will be inherited from the top-level index mappings. | | [properties](./kibana-plugin-core-server.savedobjectstypemappingdefinition.properties.md) | SavedObjectsMappingProperties | The underlying properties of the type mapping | diff --git a/docs/images/Discover-ContextView.png b/docs/discover/images/Discover-ContextView.png similarity index 100% rename from docs/images/Discover-ContextView.png rename to docs/discover/images/Discover-ContextView.png diff --git a/docs/images/Discover-Start.png b/docs/discover/images/Discover-Start.png similarity index 100% rename from docs/images/Discover-Start.png rename to docs/discover/images/Discover-Start.png diff --git a/docs/images/Expanded-Document.png b/docs/discover/images/Expanded-Document.png similarity index 100% rename from docs/images/Expanded-Document.png rename to docs/discover/images/Expanded-Document.png diff --git a/docs/images/Histogram-Time.png b/docs/discover/images/Histogram-Time.png similarity index 100% rename from docs/images/Histogram-Time.png rename to docs/discover/images/Histogram-Time.png diff --git a/docs/images/NegativeFilter.jpg b/docs/discover/images/NegativeFilter.jpg similarity index 100% rename from docs/images/NegativeFilter.jpg rename to docs/discover/images/NegativeFilter.jpg diff --git a/docs/images/PositiveFilter.jpg b/docs/discover/images/PositiveFilter.jpg similarity index 100% rename from docs/images/PositiveFilter.jpg rename to docs/discover/images/PositiveFilter.jpg diff --git a/docs/images/Timepicker-View.png b/docs/discover/images/Timepicker-View.png similarity index 100% rename from docs/images/Timepicker-View.png rename to docs/discover/images/Timepicker-View.png diff --git a/docs/images/edit_filter_query_json.png b/docs/discover/images/edit_filter_query_json.png similarity index 100% rename from docs/images/edit_filter_query_json.png rename to docs/discover/images/edit_filter_query_json.png diff --git a/docs/images/filter-field.png b/docs/discover/images/filter-field.png similarity index 100% rename from docs/images/filter-field.png rename to docs/discover/images/filter-field.png diff --git a/docs/images/time-filter-bar.png b/docs/discover/images/time-filter-bar.png similarity index 100% rename from docs/images/time-filter-bar.png rename to docs/discover/images/time-filter-bar.png diff --git a/docs/images/time-filter-calendar.png b/docs/discover/images/time-filter-calendar.png similarity index 100% rename from docs/images/time-filter-calendar.png rename to docs/discover/images/time-filter-calendar.png diff --git a/docs/images/tutorial-dashboard.png b/docs/getting-started/images/tutorial-dashboard.png similarity index 100% rename from docs/images/tutorial-dashboard.png rename to docs/getting-started/images/tutorial-dashboard.png diff --git a/docs/images/tutorial-discover-2.png b/docs/getting-started/images/tutorial-discover-2.png similarity index 100% rename from docs/images/tutorial-discover-2.png rename to docs/getting-started/images/tutorial-discover-2.png diff --git a/docs/images/tutorial-discover-3.png b/docs/getting-started/images/tutorial-discover-3.png similarity index 100% rename from docs/images/tutorial-discover-3.png rename to docs/getting-started/images/tutorial-discover-3.png diff --git a/docs/images/tutorial-full-inspect1.png b/docs/getting-started/images/tutorial-full-inspect1.png similarity index 100% rename from docs/images/tutorial-full-inspect1.png rename to docs/getting-started/images/tutorial-full-inspect1.png diff --git a/docs/images/tutorial-pattern-1.png b/docs/getting-started/images/tutorial-pattern-1.png similarity index 100% rename from docs/images/tutorial-pattern-1.png rename to docs/getting-started/images/tutorial-pattern-1.png diff --git a/docs/images/tutorial-visualize-bar-1.5.png b/docs/getting-started/images/tutorial-visualize-bar-1.5.png similarity index 100% rename from docs/images/tutorial-visualize-bar-1.5.png rename to docs/getting-started/images/tutorial-visualize-bar-1.5.png diff --git a/docs/images/tutorial-visualize-map-2.png b/docs/getting-started/images/tutorial-visualize-map-2.png similarity index 100% rename from docs/images/tutorial-visualize-map-2.png rename to docs/getting-started/images/tutorial-visualize-map-2.png diff --git a/docs/images/tutorial-visualize-md-2.png b/docs/getting-started/images/tutorial-visualize-md-2.png similarity index 100% rename from docs/images/tutorial-visualize-md-2.png rename to docs/getting-started/images/tutorial-visualize-md-2.png diff --git a/docs/images/tutorial-visualize-pie-2.png b/docs/getting-started/images/tutorial-visualize-pie-2.png similarity index 100% rename from docs/images/tutorial-visualize-pie-2.png rename to docs/getting-started/images/tutorial-visualize-pie-2.png diff --git a/docs/images/tutorial-visualize-pie-3.png b/docs/getting-started/images/tutorial-visualize-pie-3.png similarity index 100% rename from docs/images/tutorial-visualize-pie-3.png rename to docs/getting-started/images/tutorial-visualize-pie-3.png diff --git a/docs/images/tutorial-visualize-wizard-step-1.png b/docs/getting-started/images/tutorial-visualize-wizard-step-1.png similarity index 100% rename from docs/images/tutorial-visualize-wizard-step-1.png rename to docs/getting-started/images/tutorial-visualize-wizard-step-1.png diff --git a/docs/images/AddFieldButton.jpg b/docs/images/AddFieldButton.jpg deleted file mode 100644 index efd4f50e34a0b..0000000000000 Binary files a/docs/images/AddFieldButton.jpg and /dev/null differ diff --git a/docs/images/CollapseButton.jpg b/docs/images/CollapseButton.jpg deleted file mode 100644 index 38bb350d49746..0000000000000 Binary files a/docs/images/CollapseButton.jpg and /dev/null differ diff --git a/docs/images/Dashboard_Resize_Menu.png b/docs/images/Dashboard_Resize_Menu.png deleted file mode 100644 index 835d23afe40e9..0000000000000 Binary files a/docs/images/Dashboard_Resize_Menu.png and /dev/null differ diff --git a/docs/images/Dashboard_visualization_data.png b/docs/images/Dashboard_visualization_data.png deleted file mode 100644 index 9792fedf1a51a..0000000000000 Binary files a/docs/images/Dashboard_visualization_data.png and /dev/null differ diff --git a/docs/images/Discover-ContextView-FilterMontage.png b/docs/images/Discover-ContextView-FilterMontage.png deleted file mode 100644 index c990d314a6ba1..0000000000000 Binary files a/docs/images/Discover-ContextView-FilterMontage.png and /dev/null differ diff --git a/docs/images/Discover-FieldStats.jpg b/docs/images/Discover-FieldStats.jpg deleted file mode 100644 index 4092b0d7caafd..0000000000000 Binary files a/docs/images/Discover-FieldStats.jpg and /dev/null differ diff --git a/docs/images/Discover-MoveColumn.jpg b/docs/images/Discover-MoveColumn.jpg deleted file mode 100644 index 630f2a0f18dbe..0000000000000 Binary files a/docs/images/Discover-MoveColumn.jpg and /dev/null differ diff --git a/docs/images/EditVis.png b/docs/images/EditVis.png deleted file mode 100644 index 3013168200860..0000000000000 Binary files a/docs/images/EditVis.png and /dev/null differ diff --git a/docs/images/ExistsButton.jpg b/docs/images/ExistsButton.jpg deleted file mode 100644 index 0d4ede0101e73..0000000000000 Binary files a/docs/images/ExistsButton.jpg and /dev/null differ diff --git a/docs/images/ExpandButton.jpg b/docs/images/ExpandButton.jpg deleted file mode 100644 index 1ed389a25dd36..0000000000000 Binary files a/docs/images/ExpandButton.jpg and /dev/null differ diff --git a/docs/images/NYCTA-Table.jpg b/docs/images/NYCTA-Table.jpg deleted file mode 100644 index 6b4987ef4b437..0000000000000 Binary files a/docs/images/NYCTA-Table.jpg and /dev/null differ diff --git a/docs/images/NewDashboard.png b/docs/images/NewDashboard.png deleted file mode 100644 index 08e5159250134..0000000000000 Binary files a/docs/images/NewDashboard.png and /dev/null differ diff --git a/docs/images/RemoveFieldButton.jpg b/docs/images/RemoveFieldButton.jpg deleted file mode 100644 index a260dc3cff62e..0000000000000 Binary files a/docs/images/RemoveFieldButton.jpg and /dev/null differ diff --git a/docs/images/Start-Page.png b/docs/images/Start-Page.png deleted file mode 100644 index 706d4aafd75e2..0000000000000 Binary files a/docs/images/Start-Page.png and /dev/null differ diff --git a/docs/images/TimeFilter.jpg b/docs/images/TimeFilter.jpg deleted file mode 100644 index 1c8700bc05616..0000000000000 Binary files a/docs/images/TimeFilter.jpg and /dev/null differ diff --git a/docs/images/VizEditor.jpg b/docs/images/VizEditor.jpg deleted file mode 100644 index 8aabfe544a0cd..0000000000000 Binary files a/docs/images/VizEditor.jpg and /dev/null differ diff --git a/docs/images/add-column-button.png b/docs/images/add-column-button.png deleted file mode 100644 index 6f44d0facf41f..0000000000000 Binary files a/docs/images/add-column-button.png and /dev/null differ diff --git a/docs/images/add_filter_field.png b/docs/images/add_filter_field.png deleted file mode 100644 index 2052559cf5273..0000000000000 Binary files a/docs/images/add_filter_field.png and /dev/null differ diff --git a/docs/images/add_filter_operator.png b/docs/images/add_filter_operator.png deleted file mode 100644 index fd7d42a9d1b98..0000000000000 Binary files a/docs/images/add_filter_operator.png and /dev/null differ diff --git a/docs/images/add_filter_value.png b/docs/images/add_filter_value.png deleted file mode 100644 index d357c6e5a3013..0000000000000 Binary files a/docs/images/add_filter_value.png and /dev/null differ diff --git a/docs/images/auto_format_after.png b/docs/images/auto_format_after.png deleted file mode 100644 index 018e82951b64f..0000000000000 Binary files a/docs/images/auto_format_after.png and /dev/null differ diff --git a/docs/images/auto_format_before.png b/docs/images/auto_format_before.png deleted file mode 100644 index 2535aa1af5240..0000000000000 Binary files a/docs/images/auto_format_before.png and /dev/null differ diff --git a/docs/images/auto_format_bulk.png b/docs/images/auto_format_bulk.png deleted file mode 100644 index 92cb688473ab7..0000000000000 Binary files a/docs/images/auto_format_bulk.png and /dev/null differ diff --git a/docs/images/autorefresh-intervals.png b/docs/images/autorefresh-intervals.png deleted file mode 100644 index 49be46fefd4aa..0000000000000 Binary files a/docs/images/autorefresh-intervals.png and /dev/null differ diff --git a/docs/images/autorefresh-pause.png b/docs/images/autorefresh-pause.png deleted file mode 100644 index 5a83c4587c961..0000000000000 Binary files a/docs/images/autorefresh-pause.png and /dev/null differ diff --git a/docs/images/autorefresh.png b/docs/images/autorefresh.png deleted file mode 100644 index 9a6225b9007bd..0000000000000 Binary files a/docs/images/autorefresh.png and /dev/null differ diff --git a/docs/images/bar-terms-agg.png b/docs/images/bar-terms-agg.png deleted file mode 100644 index b0b62b9e53213..0000000000000 Binary files a/docs/images/bar-terms-agg.png and /dev/null differ diff --git a/docs/images/bar-terms-subagg.png b/docs/images/bar-terms-subagg.png deleted file mode 100644 index 37cf5486eff1e..0000000000000 Binary files a/docs/images/bar-terms-subagg.png and /dev/null differ diff --git a/docs/images/canvas-align-elements.gif b/docs/images/canvas-align-elements.gif deleted file mode 100644 index 0081308d68795..0000000000000 Binary files a/docs/images/canvas-align-elements.gif and /dev/null differ diff --git a/docs/images/canvas-background-color-picker.gif b/docs/images/canvas-background-color-picker.gif deleted file mode 100644 index bd22941b35f5d..0000000000000 Binary files a/docs/images/canvas-background-color-picker.gif and /dev/null differ diff --git a/docs/images/canvas-click-drag-element.gif b/docs/images/canvas-click-drag-element.gif deleted file mode 100644 index 34f4268caf6f5..0000000000000 Binary files a/docs/images/canvas-click-drag-element.gif and /dev/null differ diff --git a/docs/images/canvas-distribute-elements.gif b/docs/images/canvas-distribute-elements.gif deleted file mode 100644 index 685d76ba22e40..0000000000000 Binary files a/docs/images/canvas-distribute-elements.gif and /dev/null differ diff --git a/docs/images/canvas-download-json.gif b/docs/images/canvas-download-json.gif deleted file mode 100644 index c0c0025e508c1..0000000000000 Binary files a/docs/images/canvas-download-json.gif and /dev/null differ diff --git a/docs/images/canvas-ecommerce.png b/docs/images/canvas-ecommerce.png deleted file mode 100644 index 58c0612881341..0000000000000 Binary files a/docs/images/canvas-ecommerce.png and /dev/null differ diff --git a/docs/images/canvas-element-order.gif b/docs/images/canvas-element-order.gif deleted file mode 100644 index e2911367e7dfa..0000000000000 Binary files a/docs/images/canvas-element-order.gif and /dev/null differ diff --git a/docs/images/canvas-embed_workpad.gif b/docs/images/canvas-embed_workpad.gif deleted file mode 100644 index 97a79d775fe36..0000000000000 Binary files a/docs/images/canvas-embed_workpad.gif and /dev/null differ diff --git a/docs/images/canvas-fullscreen.gif b/docs/images/canvas-fullscreen.gif deleted file mode 100644 index 2eebd3b511000..0000000000000 Binary files a/docs/images/canvas-fullscreen.gif and /dev/null differ diff --git a/docs/images/canvas-move-pixel.gif b/docs/images/canvas-move-pixel.gif deleted file mode 100644 index 228f0f7b7e18c..0000000000000 Binary files a/docs/images/canvas-move-pixel.gif and /dev/null differ diff --git a/docs/images/canvas-resize-element.gif b/docs/images/canvas-resize-element.gif deleted file mode 100644 index d2d2ab06bbb42..0000000000000 Binary files a/docs/images/canvas-resize-element.gif and /dev/null differ diff --git a/docs/images/canvas-zoom.gif b/docs/images/canvas-zoom.gif deleted file mode 100644 index 584118d75a43f..0000000000000 Binary files a/docs/images/canvas-zoom.gif and /dev/null differ diff --git a/docs/images/canvas_create_image.png b/docs/images/canvas_create_image.png deleted file mode 100644 index 7b7c38102e4c9..0000000000000 Binary files a/docs/images/canvas_create_image.png and /dev/null differ diff --git a/docs/images/canvas_map-time-filter.gif b/docs/images/canvas_map-time-filter.gif deleted file mode 100644 index 301d7f4b44158..0000000000000 Binary files a/docs/images/canvas_map-time-filter.gif and /dev/null differ diff --git a/docs/images/canvas_share_autoplay_480.gif b/docs/images/canvas_share_autoplay_480.gif deleted file mode 100644 index 84a108e58d3dc..0000000000000 Binary files a/docs/images/canvas_share_autoplay_480.gif and /dev/null differ diff --git a/docs/images/canvas_share_hidetoolbar_480.gif b/docs/images/canvas_share_hidetoolbar_480.gif deleted file mode 100644 index 282783057776a..0000000000000 Binary files a/docs/images/canvas_share_hidetoolbar_480.gif and /dev/null differ diff --git a/docs/images/canvas_workpad_3_page.png b/docs/images/canvas_workpad_3_page.png deleted file mode 100644 index 9a60ed3d00f60..0000000000000 Binary files a/docs/images/canvas_workpad_3_page.png and /dev/null differ diff --git a/docs/images/canvas_workpad_edit_style.png b/docs/images/canvas_workpad_edit_style.png deleted file mode 100644 index d12ae2cd81b8f..0000000000000 Binary files a/docs/images/canvas_workpad_edit_style.png and /dev/null differ diff --git a/docs/images/canvas_workpad_weblog.png b/docs/images/canvas_workpad_weblog.png deleted file mode 100755 index 7b6ebee5c9554..0000000000000 Binary files a/docs/images/canvas_workpad_weblog.png and /dev/null differ diff --git a/docs/images/controls/controls_options.png b/docs/images/controls/controls_options.png deleted file mode 100644 index aab93d5cd4be0..0000000000000 Binary files a/docs/images/controls/controls_options.png and /dev/null differ diff --git a/docs/images/controls/dropdown_control_editor.png b/docs/images/controls/dropdown_control_editor.png deleted file mode 100644 index 36a360dcd275e..0000000000000 Binary files a/docs/images/controls/dropdown_control_editor.png and /dev/null differ diff --git a/docs/images/controls/range_slider_editor.png b/docs/images/controls/range_slider_editor.png deleted file mode 100644 index 8d6c5a68d1d24..0000000000000 Binary files a/docs/images/controls/range_slider_editor.png and /dev/null differ diff --git a/docs/images/discover-compass.png b/docs/images/discover-compass.png deleted file mode 100644 index 0e3c80ff75a74..0000000000000 Binary files a/docs/images/discover-compass.png and /dev/null differ diff --git a/docs/images/edit_filter_query.png b/docs/images/edit_filter_query.png deleted file mode 100644 index 367a2a8578b8b..0000000000000 Binary files a/docs/images/edit_filter_query.png and /dev/null differ diff --git a/docs/images/filter-actions.png b/docs/images/filter-actions.png deleted file mode 100644 index 92feef2f0dbbb..0000000000000 Binary files a/docs/images/filter-actions.png and /dev/null differ diff --git a/docs/images/filter-allbuttons.png b/docs/images/filter-allbuttons.png deleted file mode 100644 index 3d6951812daa7..0000000000000 Binary files a/docs/images/filter-allbuttons.png and /dev/null differ diff --git a/docs/images/filter-sample.png b/docs/images/filter-sample.png deleted file mode 100644 index 9d2540720a5a2..0000000000000 Binary files a/docs/images/filter-sample.png and /dev/null differ diff --git a/docs/images/goal.png b/docs/images/goal.png deleted file mode 100644 index 04f16e8cd3e74..0000000000000 Binary files a/docs/images/goal.png and /dev/null differ diff --git a/docs/images/history.png b/docs/images/history.png deleted file mode 100644 index 8e6674e1f2c69..0000000000000 Binary files a/docs/images/history.png and /dev/null differ diff --git a/docs/images/labelbutton.png b/docs/images/labelbutton.png deleted file mode 100644 index 287a588802384..0000000000000 Binary files a/docs/images/labelbutton.png and /dev/null differ diff --git a/docs/images/lens_remove_layer.png b/docs/images/lens_remove_layer.png deleted file mode 100644 index 4184e5b846870..0000000000000 Binary files a/docs/images/lens_remove_layer.png and /dev/null differ diff --git a/docs/images/management-index-management.png b/docs/images/management-index-management.png deleted file mode 100644 index 1b1ff9226147c..0000000000000 Binary files a/docs/images/management-index-management.png and /dev/null differ diff --git a/docs/images/management-license.png b/docs/images/management-license.png deleted file mode 100644 index 3347aec8632e4..0000000000000 Binary files a/docs/images/management-license.png and /dev/null differ diff --git a/docs/images/management-upgrade-assistant-8.0.png b/docs/images/management-upgrade-assistant-8.0.png deleted file mode 100644 index 4b37262414039..0000000000000 Binary files a/docs/images/management-upgrade-assistant-8.0.png and /dev/null differ diff --git a/docs/images/management-watcher-buttons.png b/docs/images/management-watcher-buttons.png deleted file mode 100644 index ce114ccf1bac9..0000000000000 Binary files a/docs/images/management-watcher-buttons.png and /dev/null differ diff --git a/docs/images/management_rolled_dashboard.png b/docs/images/management_rolled_dashboard.png deleted file mode 100755 index db731420fb96a..0000000000000 Binary files a/docs/images/management_rolled_dashboard.png and /dev/null differ diff --git a/docs/images/management_rollups_visualization.png b/docs/images/management_rollups_visualization.png deleted file mode 100755 index bba3b6e91a953..0000000000000 Binary files a/docs/images/management_rollups_visualization.png and /dev/null differ diff --git a/docs/images/markdown-example.png b/docs/images/markdown-example.png deleted file mode 100644 index 79daa1298883d..0000000000000 Binary files a/docs/images/markdown-example.png and /dev/null differ diff --git a/docs/images/multiple_requests.png b/docs/images/multiple_requests.png deleted file mode 100644 index e4fd010d54b4b..0000000000000 Binary files a/docs/images/multiple_requests.png and /dev/null differ diff --git a/docs/images/regionmap.png b/docs/images/regionmap.png deleted file mode 100644 index 97f2594e8bee6..0000000000000 Binary files a/docs/images/regionmap.png and /dev/null differ diff --git a/docs/images/search-button.jpg b/docs/images/search-button.jpg deleted file mode 100644 index b7787cac4bf6a..0000000000000 Binary files a/docs/images/search-button.jpg and /dev/null differ diff --git a/docs/images/security_base_all.png b/docs/images/security_base_all.png deleted file mode 100644 index 2aef42132ef21..0000000000000 Binary files a/docs/images/security_base_all.png and /dev/null differ diff --git a/docs/images/share-short-link.png b/docs/images/share-short-link.png deleted file mode 100644 index bf7f7782c4e2a..0000000000000 Binary files a/docs/images/share-short-link.png and /dev/null differ diff --git a/docs/images/time-filter-absolute.jpg b/docs/images/time-filter-absolute.jpg deleted file mode 100644 index bc54d57f0f737..0000000000000 Binary files a/docs/images/time-filter-absolute.jpg and /dev/null differ diff --git a/docs/images/time-filter-relative.jpg b/docs/images/time-filter-relative.jpg deleted file mode 100644 index 77beca3a3fd46..0000000000000 Binary files a/docs/images/time-filter-relative.jpg and /dev/null differ diff --git a/docs/images/time-filter.jpg b/docs/images/time-filter.jpg deleted file mode 100644 index e437f314d849d..0000000000000 Binary files a/docs/images/time-filter.jpg and /dev/null differ diff --git a/docs/images/time-picker-step.jpg b/docs/images/time-picker-step.jpg deleted file mode 100644 index 90c749776bb5d..0000000000000 Binary files a/docs/images/time-picker-step.jpg and /dev/null differ diff --git a/docs/images/time-picker.jpg b/docs/images/time-picker.jpg deleted file mode 100644 index 25830082d5919..0000000000000 Binary files a/docs/images/time-picker.jpg and /dev/null differ diff --git a/docs/images/timelion-arg-help.jpg b/docs/images/timelion-arg-help.jpg deleted file mode 100644 index 3e471c861d46b..0000000000000 Binary files a/docs/images/timelion-arg-help.jpg and /dev/null differ diff --git a/docs/images/timelion-read-only-badge.png b/docs/images/timelion-read-only-badge.png deleted file mode 100644 index 19ffbfed6335a..0000000000000 Binary files a/docs/images/timelion-read-only-badge.png and /dev/null differ diff --git a/docs/images/timelion-save01.png b/docs/images/timelion-save01.png deleted file mode 100644 index 47a33c2d36d43..0000000000000 Binary files a/docs/images/timelion-save01.png and /dev/null differ diff --git a/docs/images/timelion-save02.png b/docs/images/timelion-save02.png deleted file mode 100644 index 348b084ee5259..0000000000000 Binary files a/docs/images/timelion-save02.png and /dev/null differ diff --git a/docs/images/tsvb-annotations.png b/docs/images/tsvb-annotations.png deleted file mode 100644 index 22238db7e9e91..0000000000000 Binary files a/docs/images/tsvb-annotations.png and /dev/null differ diff --git a/docs/images/tsvb-data-tab-derivative-example.png b/docs/images/tsvb-data-tab-derivative-example.png deleted file mode 100644 index 66368baf1e16a..0000000000000 Binary files a/docs/images/tsvb-data-tab-derivative-example.png and /dev/null differ diff --git a/docs/images/tsvb-data-tab-label.png b/docs/images/tsvb-data-tab-label.png deleted file mode 100644 index 43d1fc64f4446..0000000000000 Binary files a/docs/images/tsvb-data-tab-label.png and /dev/null differ diff --git a/docs/images/tsvb-data-tab-series-options-time-series.png b/docs/images/tsvb-data-tab-series-options-time-series.png deleted file mode 100644 index 4c7ddadd38d95..0000000000000 Binary files a/docs/images/tsvb-data-tab-series-options-time-series.png and /dev/null differ diff --git a/docs/images/tsvb-data-tab-series-options.png b/docs/images/tsvb-data-tab-series-options.png deleted file mode 100644 index afadc3349bfe4..0000000000000 Binary files a/docs/images/tsvb-data-tab-series-options.png and /dev/null differ diff --git a/docs/images/tutorial-full-inspect2.png b/docs/images/tutorial-full-inspect2.png deleted file mode 100644 index 23c840f545ec3..0000000000000 Binary files a/docs/images/tutorial-full-inspect2.png and /dev/null differ diff --git a/docs/images/tutorial-sample-discover-2.png b/docs/images/tutorial-sample-discover-2.png deleted file mode 100644 index 4f4b2dc920ccb..0000000000000 Binary files a/docs/images/tutorial-sample-discover-2.png and /dev/null differ diff --git a/docs/images/tutorial-sample-inspect2.png b/docs/images/tutorial-sample-inspect2.png deleted file mode 100644 index b487d21e5cc02..0000000000000 Binary files a/docs/images/tutorial-sample-inspect2.png and /dev/null differ diff --git a/docs/images/tutorial-visualize-pie-1.png b/docs/images/tutorial-visualize-pie-1.png deleted file mode 100644 index 109829c01f28c..0000000000000 Binary files a/docs/images/tutorial-visualize-pie-1.png and /dev/null differ diff --git a/docs/images/visualize-flow.png b/docs/images/visualize-flow.png deleted file mode 100644 index bc00ff52a8d6e..0000000000000 Binary files a/docs/images/visualize-flow.png and /dev/null differ diff --git a/docs/images/visualize-icon.png b/docs/images/visualize-icon.png deleted file mode 100644 index af7ad18e9bf79..0000000000000 Binary files a/docs/images/visualize-icon.png and /dev/null differ diff --git a/docs/images/visualize_coordinate_map_example.png b/docs/images/visualize_coordinate_map_example.png deleted file mode 100644 index 24f03376adade..0000000000000 Binary files a/docs/images/visualize_coordinate_map_example.png and /dev/null differ diff --git a/docs/images/visualize_region_map_example.png b/docs/images/visualize_region_map_example.png deleted file mode 100644 index cf89e92625ece..0000000000000 Binary files a/docs/images/visualize_region_map_example.png and /dev/null differ diff --git a/docs/images/viz-fit-bounds.png b/docs/images/viz-fit-bounds.png deleted file mode 100644 index 9c0ddb89d7ddd..0000000000000 Binary files a/docs/images/viz-fit-bounds.png and /dev/null differ diff --git a/docs/images/viz-lat-long-filter.png b/docs/images/viz-lat-long-filter.png deleted file mode 100644 index 30c139b224565..0000000000000 Binary files a/docs/images/viz-lat-long-filter.png and /dev/null differ diff --git a/docs/images/viz-zoom.png b/docs/images/viz-zoom.png deleted file mode 100644 index 661e053130882..0000000000000 Binary files a/docs/images/viz-zoom.png and /dev/null differ diff --git a/docs/images/follower_indices.png b/docs/management/alerting/images/follower_indices.png similarity index 100% rename from docs/images/follower_indices.png rename to docs/management/alerting/images/follower_indices.png diff --git a/docs/images/actions_icon.png b/docs/management/images/actions_icon.png similarity index 100% rename from docs/images/actions_icon.png rename to docs/management/images/actions_icon.png diff --git a/docs/images/add_remote_cluster.png b/docs/management/images/add_remote_cluster.png similarity index 100% rename from docs/images/add_remote_cluster.png rename to docs/management/images/add_remote_cluster.png diff --git a/docs/images/auto_follow_pattern.png b/docs/management/images/auto_follow_pattern.png similarity index 100% rename from docs/images/auto_follow_pattern.png rename to docs/management/images/auto_follow_pattern.png diff --git a/docs/images/colorformatter.png b/docs/management/images/colorformatter.png similarity index 100% rename from docs/images/colorformatter.png rename to docs/management/images/colorformatter.png diff --git a/docs/images/cross-cluster-replication-list-view.png b/docs/management/images/cross-cluster-replication-list-view.png similarity index 100% rename from docs/images/cross-cluster-replication-list-view.png rename to docs/management/images/cross-cluster-replication-list-view.png diff --git a/docs/images/index-lifecycle-policies-create.png b/docs/management/images/index-lifecycle-policies-create.png similarity index 100% rename from docs/images/index-lifecycle-policies-create.png rename to docs/management/images/index-lifecycle-policies-create.png diff --git a/docs/images/index_lifecycle_policies_options.png b/docs/management/images/index_lifecycle_policies_options.png similarity index 100% rename from docs/images/index_lifecycle_policies_options.png rename to docs/management/images/index_lifecycle_policies_options.png diff --git a/docs/images/index_management_add_policy.png b/docs/management/images/index_management_add_policy.png similarity index 100% rename from docs/images/index_management_add_policy.png rename to docs/management/images/index_management_add_policy.png diff --git a/docs/images/management-create-rollup-bar-chart.png b/docs/management/images/management-create-rollup-bar-chart.png similarity index 100% rename from docs/images/management-create-rollup-bar-chart.png rename to docs/management/images/management-create-rollup-bar-chart.png diff --git a/docs/images/management-index-patterns.png b/docs/management/images/management-index-patterns.png similarity index 100% rename from docs/images/management-index-patterns.png rename to docs/management/images/management-index-patterns.png diff --git a/docs/images/management-index-read-only-badge.png b/docs/management/images/management-index-read-only-badge.png similarity index 100% rename from docs/images/management-index-read-only-badge.png rename to docs/management/images/management-index-read-only-badge.png diff --git a/docs/images/management-index-templates-mappings.png b/docs/management/images/management-index-templates-mappings.png similarity index 100% rename from docs/images/management-index-templates-mappings.png rename to docs/management/images/management-index-templates-mappings.png diff --git a/docs/images/management-index-templates.png b/docs/management/images/management-index-templates.png similarity index 100% rename from docs/images/management-index-templates.png rename to docs/management/images/management-index-templates.png diff --git a/docs/management/images/management-license.png b/docs/management/images/management-license.png new file mode 100644 index 0000000000000..8df9402939b2e Binary files /dev/null and b/docs/management/images/management-license.png differ diff --git a/docs/images/management-rollup-index-pattern.png b/docs/management/images/management-rollup-index-pattern.png similarity index 100% rename from docs/images/management-rollup-index-pattern.png rename to docs/management/images/management-rollup-index-pattern.png diff --git a/docs/images/management-saved-objects.png b/docs/management/images/management-saved-objects.png similarity index 100% rename from docs/images/management-saved-objects.png rename to docs/management/images/management-saved-objects.png diff --git a/docs/images/management-upgrade-assistant-9.0.png b/docs/management/images/management-upgrade-assistant-9.0.png similarity index 100% rename from docs/images/management-upgrade-assistant-9.0.png rename to docs/management/images/management-upgrade-assistant-9.0.png diff --git a/docs/images/management_create_rollup_job.png b/docs/management/images/management_create_rollup_job.png similarity index 100% rename from docs/images/management_create_rollup_job.png rename to docs/management/images/management_create_rollup_job.png diff --git a/docs/images/management_create_rollup_menu.png b/docs/management/images/management_create_rollup_menu.png similarity index 100% rename from docs/images/management_create_rollup_menu.png rename to docs/management/images/management_create_rollup_menu.png diff --git a/docs/images/management_index_create_wizard.png b/docs/management/images/management_index_create_wizard.png similarity index 100% rename from docs/images/management_index_create_wizard.png rename to docs/management/images/management_index_create_wizard.png diff --git a/docs/images/management_index_details.png b/docs/management/images/management_index_details.png similarity index 100% rename from docs/images/management_index_details.png rename to docs/management/images/management_index_details.png diff --git a/docs/images/management_index_labels.png b/docs/management/images/management_index_labels.png similarity index 100% rename from docs/images/management_index_labels.png rename to docs/management/images/management_index_labels.png diff --git a/docs/images/management_rollup_job_dashboard.png b/docs/management/images/management_rollup_job_dashboard.png similarity index 100% rename from docs/images/management_rollup_job_dashboard.png rename to docs/management/images/management_rollup_job_dashboard.png diff --git a/docs/images/management_rollup_job_details.png b/docs/management/images/management_rollup_job_details.png similarity index 100% rename from docs/images/management_rollup_job_details.png rename to docs/management/images/management_rollup_job_details.png diff --git a/docs/images/management_rollup_job_vis.png b/docs/management/images/management_rollup_job_vis.png similarity index 100% rename from docs/images/management_rollup_job_vis.png rename to docs/management/images/management_rollup_job_vis.png diff --git a/docs/images/management_rollup_list.png b/docs/management/images/management_rollup_list.png similarity index 100% rename from docs/images/management_rollup_list.png rename to docs/management/images/management_rollup_list.png diff --git a/docs/images/remote-clusters-list-view.png b/docs/management/images/remote-clusters-list-view.png similarity index 100% rename from docs/images/remote-clusters-list-view.png rename to docs/management/images/remote-clusters-list-view.png diff --git a/docs/images/settings-read-only-badge.png b/docs/management/images/settings-read-only-badge.png similarity index 100% rename from docs/images/settings-read-only-badge.png rename to docs/management/images/settings-read-only-badge.png diff --git a/docs/images/tutorial-ilm-custom-policy.png b/docs/management/images/tutorial-ilm-custom-policy.png similarity index 100% rename from docs/images/tutorial-ilm-custom-policy.png rename to docs/management/images/tutorial-ilm-custom-policy.png diff --git a/docs/images/tutorial-ilm-delete-phase-creation.png b/docs/management/images/tutorial-ilm-delete-phase-creation.png similarity index 100% rename from docs/images/tutorial-ilm-delete-phase-creation.png rename to docs/management/images/tutorial-ilm-delete-phase-creation.png diff --git a/docs/images/tutorial-ilm-delete-rollover.png b/docs/management/images/tutorial-ilm-delete-rollover.png similarity index 100% rename from docs/images/tutorial-ilm-delete-rollover.png rename to docs/management/images/tutorial-ilm-delete-rollover.png diff --git a/docs/images/tutorial-ilm-hotphaserollover-default.png b/docs/management/images/tutorial-ilm-hotphaserollover-default.png similarity index 100% rename from docs/images/tutorial-ilm-hotphaserollover-default.png rename to docs/management/images/tutorial-ilm-hotphaserollover-default.png diff --git a/docs/images/tutorial-ilm-modify-default-warm-phase-rollover.png b/docs/management/images/tutorial-ilm-modify-default-warm-phase-rollover.png similarity index 100% rename from docs/images/tutorial-ilm-modify-default-warm-phase-rollover.png rename to docs/management/images/tutorial-ilm-modify-default-warm-phase-rollover.png diff --git a/docs/management/managing-licenses.asciidoc b/docs/management/managing-licenses.asciidoc index 6cd6657a0aaeb..99cfd12eeade9 100644 --- a/docs/management/managing-licenses.asciidoc +++ b/docs/management/managing-licenses.asciidoc @@ -1,28 +1,27 @@ [[managing-licenses]] == License Management -When you install the default distribution of {kib}, you receive a basic license -with no expiration date. For the full list of free features that are included in -the basic license, refer to https://www.elastic.co/subscriptions[the subscription page]. +When you install the default distribution of {kib}, you receive free features +with no expiration date. For the full list of features, refer to +{subscriptions}. -If you want to try out the full set of platinum features, you can activate a -30-day trial license. To view the -status of your license, start a trial, or install a new license, open the menu, then go to *Stack Management > {es} > License Management*. +If you want to try out the full set of features, you can activate a free 30-day +trial. To view the status of your license, start a trial, or install a new +license, open the menu, then go to *Stack Management > {es} > License Management*. NOTE: You can start a trial only if your cluster has not already activated a trial license for the current major product version. For example, if you have already activated a trial for 6.0, you cannot start a new trial until -7.0. You can, however, contact `info@elastic.co` to request an extended trial -license. +7.0. You can, however, request an extended trial at {extendtrial}. When you activate a new license level, new features appear in *Stack Management*. [role="screenshot"] image::images/management-license.png[] -At the end of the trial period, the platinum features operate in a -<>. You can revert to a basic license, -extend the trial, or purchase a subscription. +At the end of the trial period, some features operate in a +<>. You can revert to Basic, extend the trial, +or purchase a subscription. TIP: If {security-features} are enabled, unless you have a trial license, you must configure Transport Layer Security (TLS) in {es}. diff --git a/docs/images/add-data-fv.png b/docs/setup/images/add-data-fv.png similarity index 100% rename from docs/images/add-data-fv.png rename to docs/setup/images/add-data-fv.png diff --git a/docs/images/add-data-tutorials.png b/docs/setup/images/add-data-tutorials.png similarity index 100% rename from docs/images/add-data-tutorials.png rename to docs/setup/images/add-data-tutorials.png diff --git a/docs/images/data-viz-homepage.jpg b/docs/setup/images/data-viz-homepage.jpg similarity index 100% rename from docs/images/data-viz-homepage.jpg rename to docs/setup/images/data-viz-homepage.jpg diff --git a/docs/images/kibana-status-page-7_5_0.png b/docs/setup/images/kibana-status-page-7_5_0.png similarity index 100% rename from docs/images/kibana-status-page-7_5_0.png rename to docs/setup/images/kibana-status-page-7_5_0.png diff --git a/docs/user/alerting/action-types/pagerduty.asciidoc b/docs/user/alerting/action-types/pagerduty.asciidoc index 0468ab042e57e..5fd85a1045265 100644 --- a/docs/user/alerting/action-types/pagerduty.asciidoc +++ b/docs/user/alerting/action-types/pagerduty.asciidoc @@ -68,11 +68,11 @@ Then, select the *Integrations* tab and click the *New Integration* button. * If you are creating a new service for your integration, go to https://support.pagerduty.com/docs/services-and-integrations#section-configuring-services-and-integrations[Configuring Services and Integrations] -and follow the steps outlined in the *Create a New Service* section, selecting *Elastic* as the *Integration Type* in step 4. +and follow the steps outlined in the *Create a New Service* section, selecting *Elastic Alerts* as the *Integration Type* in step 4. Continue with the <> section once you have finished these steps. . Enter an *Integration Name* in the format Elastic-service-name (for example, Elastic-Alerting or Kibana-APM-Alerting) -and select Elastic from the *Integration Type* menu. +and select *Elastic Alerts* from the *Integration Type* menu. . Click *Add Integration* to save your new integration. + You will be redirected to the *Integrations* tab for your service. An Integration Key is generated on this screen. diff --git a/docs/images/Dashboard_add_new_visualization.png b/docs/user/dashboard/images/Dashboard_add_new_visualization.png similarity index 100% rename from docs/images/Dashboard_add_new_visualization.png rename to docs/user/dashboard/images/Dashboard_add_new_visualization.png diff --git a/docs/images/Dashboard_add_visualization.png b/docs/user/dashboard/images/Dashboard_add_visualization.png similarity index 100% rename from docs/images/Dashboard_add_visualization.png rename to docs/user/dashboard/images/Dashboard_add_visualization.png diff --git a/docs/images/Dashboard_example.png b/docs/user/dashboard/images/Dashboard_example.png similarity index 100% rename from docs/images/Dashboard_example.png rename to docs/user/dashboard/images/Dashboard_example.png diff --git a/docs/images/Dashboard_inspect.png b/docs/user/dashboard/images/Dashboard_inspect.png similarity index 100% rename from docs/images/Dashboard_inspect.png rename to docs/user/dashboard/images/Dashboard_inspect.png diff --git a/docs/images/clone_panel.gif b/docs/user/dashboard/images/clone_panel.gif similarity index 100% rename from docs/images/clone_panel.gif rename to docs/user/dashboard/images/clone_panel.gif diff --git a/docs/images/dashboard-read-only-badge.png b/docs/user/dashboard/images/dashboard-read-only-badge.png similarity index 100% rename from docs/images/dashboard-read-only-badge.png rename to docs/user/dashboard/images/dashboard-read-only-badge.png diff --git a/docs/images/time_range_per_panel.gif b/docs/user/dashboard/images/time_range_per_panel.gif similarity index 100% rename from docs/images/time_range_per_panel.gif rename to docs/user/dashboard/images/time_range_per_panel.gif diff --git a/docs/images/intro-dashboard.png b/docs/user/introduction/images/intro-dashboard.png similarity index 100% rename from docs/images/intro-dashboard.png rename to docs/user/introduction/images/intro-dashboard.png diff --git a/docs/images/intro-data-tutorial.png b/docs/user/introduction/images/intro-data-tutorial.png similarity index 100% rename from docs/images/intro-data-tutorial.png rename to docs/user/introduction/images/intro-data-tutorial.png diff --git a/docs/images/intro-discover.png b/docs/user/introduction/images/intro-discover.png similarity index 100% rename from docs/images/intro-discover.png rename to docs/user/introduction/images/intro-discover.png diff --git a/docs/images/intro-kibana.png b/docs/user/introduction/images/intro-kibana.png similarity index 100% rename from docs/images/intro-kibana.png rename to docs/user/introduction/images/intro-kibana.png diff --git a/docs/images/intro-management.png b/docs/user/introduction/images/intro-management.png similarity index 100% rename from docs/images/intro-management.png rename to docs/user/introduction/images/intro-management.png diff --git a/docs/images/intro-spaces.jpg b/docs/user/introduction/images/intro-spaces.jpg similarity index 100% rename from docs/images/intro-spaces.jpg rename to docs/user/introduction/images/intro-spaces.jpg diff --git a/docs/images/monitoring-dashboard.png b/docs/user/monitoring/images/monitoring-dashboard.png similarity index 100% rename from docs/images/monitoring-dashboard.png rename to docs/user/monitoring/images/monitoring-dashboard.png diff --git a/docs/images/report-automate-csv.png b/docs/user/reporting/images/report-automate-csv.png similarity index 100% rename from docs/images/report-automate-csv.png rename to docs/user/reporting/images/report-automate-csv.png diff --git a/docs/images/report-automate-pdf.png b/docs/user/reporting/images/report-automate-pdf.png similarity index 100% rename from docs/images/report-automate-pdf.png rename to docs/user/reporting/images/report-automate-pdf.png diff --git a/docs/user/reporting/index.asciidoc b/docs/user/reporting/index.asciidoc index 4123912b79237..6acdbbe3f0a99 100644 --- a/docs/user/reporting/index.asciidoc +++ b/docs/user/reporting/index.asciidoc @@ -19,7 +19,7 @@ image::user/reporting/images/share-button.png["Share"] [float] == Setup -{reporting} is automatically enabled in {kib}. The first time {kib} runs, it extracts a custom build for the Chromium web browser, which +{reporting} is automatically enabled in {kib}. It runs a custom build of the Chromium web browser, which runs on the server in headless mode to load {kib} and capture the rendered {kib} charts as images. Chromium is an open-source project not related to Elastic, but the Chromium binary for {kib} has been custom-built by Elastic to ensure it diff --git a/docs/images/add-bucket.png b/docs/visualize/images/add-bucket.png similarity index 100% rename from docs/images/add-bucket.png rename to docs/visualize/images/add-bucket.png diff --git a/docs/images/apply-changes-button.png b/docs/visualize/images/apply-changes-button.png similarity index 100% rename from docs/images/apply-changes-button.png rename to docs/visualize/images/apply-changes-button.png diff --git a/docs/images/color-picker.png b/docs/visualize/images/color-picker.png similarity index 100% rename from docs/images/color-picker.png rename to docs/visualize/images/color-picker.png diff --git a/docs/images/dashboard-controls.png b/docs/visualize/images/dashboard-controls.png similarity index 100% rename from docs/images/dashboard-controls.png rename to docs/visualize/images/dashboard-controls.png diff --git a/docs/images/gauge.png b/docs/visualize/images/gauge.png similarity index 100% rename from docs/images/gauge.png rename to docs/visualize/images/gauge.png diff --git a/docs/images/lens_data_info.png b/docs/visualize/images/lens_data_info.png similarity index 100% rename from docs/images/lens_data_info.png rename to docs/visualize/images/lens_data_info.png diff --git a/docs/images/lens_drag_drop.gif b/docs/visualize/images/lens_drag_drop.gif similarity index 100% rename from docs/images/lens_drag_drop.gif rename to docs/visualize/images/lens_drag_drop.gif diff --git a/docs/images/lens_suggestions.gif b/docs/visualize/images/lens_suggestions.gif similarity index 100% rename from docs/images/lens_suggestions.gif rename to docs/visualize/images/lens_suggestions.gif diff --git a/docs/images/lens_tutorial_1.png b/docs/visualize/images/lens_tutorial_1.png similarity index 100% rename from docs/images/lens_tutorial_1.png rename to docs/visualize/images/lens_tutorial_1.png diff --git a/docs/images/lens_tutorial_2.png b/docs/visualize/images/lens_tutorial_2.png similarity index 100% rename from docs/images/lens_tutorial_2.png rename to docs/visualize/images/lens_tutorial_2.png diff --git a/docs/images/lens_tutorial_3.png b/docs/visualize/images/lens_tutorial_3.png similarity index 100% rename from docs/images/lens_tutorial_3.png rename to docs/visualize/images/lens_tutorial_3.png diff --git a/docs/images/lens_viz_types.png b/docs/visualize/images/lens_viz_types.png similarity index 100% rename from docs/images/lens_viz_types.png rename to docs/visualize/images/lens_viz_types.png diff --git a/docs/images/markdown_example_1.png b/docs/visualize/images/markdown_example_1.png similarity index 100% rename from docs/images/markdown_example_1.png rename to docs/visualize/images/markdown_example_1.png diff --git a/docs/images/markdown_example_2.png b/docs/visualize/images/markdown_example_2.png similarity index 100% rename from docs/images/markdown_example_2.png rename to docs/visualize/images/markdown_example_2.png diff --git a/docs/images/markdown_example_3.png b/docs/visualize/images/markdown_example_3.png similarity index 100% rename from docs/images/markdown_example_3.png rename to docs/visualize/images/markdown_example_3.png diff --git a/docs/images/markdown_example_4.png b/docs/visualize/images/markdown_example_4.png similarity index 100% rename from docs/images/markdown_example_4.png rename to docs/visualize/images/markdown_example_4.png diff --git a/docs/images/timelion-conditional01.png b/docs/visualize/images/timelion-conditional01.png similarity index 100% rename from docs/images/timelion-conditional01.png rename to docs/visualize/images/timelion-conditional01.png diff --git a/docs/images/timelion-conditional02.png b/docs/visualize/images/timelion-conditional02.png similarity index 100% rename from docs/images/timelion-conditional02.png rename to docs/visualize/images/timelion-conditional02.png diff --git a/docs/images/timelion-conditional03.png b/docs/visualize/images/timelion-conditional03.png similarity index 100% rename from docs/images/timelion-conditional03.png rename to docs/visualize/images/timelion-conditional03.png diff --git a/docs/images/timelion-conditional04.png b/docs/visualize/images/timelion-conditional04.png similarity index 100% rename from docs/images/timelion-conditional04.png rename to docs/visualize/images/timelion-conditional04.png diff --git a/docs/images/timelion-create01.png b/docs/visualize/images/timelion-create01.png similarity index 100% rename from docs/images/timelion-create01.png rename to docs/visualize/images/timelion-create01.png diff --git a/docs/images/timelion-create02.png b/docs/visualize/images/timelion-create02.png similarity index 100% rename from docs/images/timelion-create02.png rename to docs/visualize/images/timelion-create02.png diff --git a/docs/images/timelion-create03.png b/docs/visualize/images/timelion-create03.png similarity index 100% rename from docs/images/timelion-create03.png rename to docs/visualize/images/timelion-create03.png diff --git a/docs/images/timelion-customize01.png b/docs/visualize/images/timelion-customize01.png similarity index 100% rename from docs/images/timelion-customize01.png rename to docs/visualize/images/timelion-customize01.png diff --git a/docs/images/timelion-customize02.png b/docs/visualize/images/timelion-customize02.png similarity index 100% rename from docs/images/timelion-customize02.png rename to docs/visualize/images/timelion-customize02.png diff --git a/docs/images/timelion-customize03.png b/docs/visualize/images/timelion-customize03.png similarity index 100% rename from docs/images/timelion-customize03.png rename to docs/visualize/images/timelion-customize03.png diff --git a/docs/images/timelion-customize04.png b/docs/visualize/images/timelion-customize04.png similarity index 100% rename from docs/images/timelion-customize04.png rename to docs/visualize/images/timelion-customize04.png diff --git a/docs/images/timelion-math01.png b/docs/visualize/images/timelion-math01.png similarity index 100% rename from docs/images/timelion-math01.png rename to docs/visualize/images/timelion-math01.png diff --git a/docs/images/timelion-math02.png b/docs/visualize/images/timelion-math02.png similarity index 100% rename from docs/images/timelion-math02.png rename to docs/visualize/images/timelion-math02.png diff --git a/docs/images/timelion-math03.png b/docs/visualize/images/timelion-math03.png similarity index 100% rename from docs/images/timelion-math03.png rename to docs/visualize/images/timelion-math03.png diff --git a/docs/images/timelion-math04.png b/docs/visualize/images/timelion-math04.png similarity index 100% rename from docs/images/timelion-math04.png rename to docs/visualize/images/timelion-math04.png diff --git a/docs/images/timelion-math05.png b/docs/visualize/images/timelion-math05.png similarity index 100% rename from docs/images/timelion-math05.png rename to docs/visualize/images/timelion-math05.png diff --git a/docs/images/tsvb-gauge.png b/docs/visualize/images/tsvb-gauge.png similarity index 100% rename from docs/images/tsvb-gauge.png rename to docs/visualize/images/tsvb-gauge.png diff --git a/docs/images/tsvb-markdown.png b/docs/visualize/images/tsvb-markdown.png similarity index 100% rename from docs/images/tsvb-markdown.png rename to docs/visualize/images/tsvb-markdown.png diff --git a/docs/images/tsvb-metric.png b/docs/visualize/images/tsvb-metric.png similarity index 100% rename from docs/images/tsvb-metric.png rename to docs/visualize/images/tsvb-metric.png diff --git a/docs/images/tsvb-screenshot.png b/docs/visualize/images/tsvb-screenshot.png similarity index 100% rename from docs/images/tsvb-screenshot.png rename to docs/visualize/images/tsvb-screenshot.png diff --git a/docs/images/tsvb-table.png b/docs/visualize/images/tsvb-table.png similarity index 100% rename from docs/images/tsvb-table.png rename to docs/visualize/images/tsvb-table.png diff --git a/docs/images/tsvb-top-n.png b/docs/visualize/images/tsvb-top-n.png similarity index 100% rename from docs/images/tsvb-top-n.png rename to docs/visualize/images/tsvb-top-n.png diff --git a/docs/images/vega_lite_default.png b/docs/visualize/images/vega_lite_default.png similarity index 100% rename from docs/images/vega_lite_default.png rename to docs/visualize/images/vega_lite_default.png diff --git a/docs/images/visualize-date-histogram-split-1.png b/docs/visualize/images/visualize-date-histogram-split-1.png similarity index 100% rename from docs/images/visualize-date-histogram-split-1.png rename to docs/visualize/images/visualize-date-histogram-split-1.png diff --git a/docs/images/visualize-date-histogram-split-2.png b/docs/visualize/images/visualize-date-histogram-split-2.png similarity index 100% rename from docs/images/visualize-date-histogram-split-2.png rename to docs/visualize/images/visualize-date-histogram-split-2.png diff --git a/docs/images/visualize-date-histogram.png b/docs/visualize/images/visualize-date-histogram.png similarity index 100% rename from docs/images/visualize-date-histogram.png rename to docs/visualize/images/visualize-date-histogram.png diff --git a/docs/images/visualize-drag-reorder.png b/docs/visualize/images/visualize-drag-reorder.png similarity index 100% rename from docs/images/visualize-drag-reorder.png rename to docs/visualize/images/visualize-drag-reorder.png diff --git a/docs/images/visualize_heat_map_example.png b/docs/visualize/images/visualize_heat_map_example.png similarity index 100% rename from docs/images/visualize_heat_map_example.png rename to docs/visualize/images/visualize_heat_map_example.png diff --git a/examples/bfetch_explorer/kibana.json b/examples/bfetch_explorer/kibana.json index 0039e9647bf83..f32cdfc13a1fe 100644 --- a/examples/bfetch_explorer/kibana.json +++ b/examples/bfetch_explorer/kibana.json @@ -5,5 +5,6 @@ "server": true, "ui": true, "requiredPlugins": ["bfetch", "developerExamples"], - "optionalPlugins": [] + "optionalPlugins": [], + "requiredBundles": ["kibanaReact"] } diff --git a/examples/dashboard_embeddable_examples/kibana.json b/examples/dashboard_embeddable_examples/kibana.json index bb2ced569edb5..807229fad9dcf 100644 --- a/examples/dashboard_embeddable_examples/kibana.json +++ b/examples/dashboard_embeddable_examples/kibana.json @@ -5,5 +5,6 @@ "server": false, "ui": true, "requiredPlugins": ["embeddable", "embeddableExamples", "dashboard", "developerExamples"], - "optionalPlugins": [] + "optionalPlugins": [], + "requiredBundles": ["esUiShared"] } diff --git a/examples/embeddable_examples/common/book_saved_object_attributes.ts b/examples/embeddable_examples/common/book_saved_object_attributes.ts new file mode 100644 index 0000000000000..62c08b7b81362 --- /dev/null +++ b/examples/embeddable_examples/common/book_saved_object_attributes.ts @@ -0,0 +1,28 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { SavedObjectAttributes } from '../../../src/core/types'; + +export const BOOK_SAVED_OBJECT = 'book'; + +export interface BookSavedObjectAttributes extends SavedObjectAttributes { + title: string; + author?: string; + readIt?: boolean; +} diff --git a/examples/embeddable_examples/common/index.ts b/examples/embeddable_examples/common/index.ts index 726420fb9bdc3..55715113a12a2 100644 --- a/examples/embeddable_examples/common/index.ts +++ b/examples/embeddable_examples/common/index.ts @@ -18,3 +18,4 @@ */ export { TodoSavedObjectAttributes } from './todo_saved_object_attributes'; +export { BookSavedObjectAttributes, BOOK_SAVED_OBJECT } from './book_saved_object_attributes'; diff --git a/examples/embeddable_examples/kibana.json b/examples/embeddable_examples/kibana.json index 486c6322fad93..771c19cfdbd3d 100644 --- a/examples/embeddable_examples/kibana.json +++ b/examples/embeddable_examples/kibana.json @@ -4,7 +4,8 @@ "kibanaVersion": "kibana", "server": true, "ui": true, - "requiredPlugins": ["embeddable"], + "requiredPlugins": ["embeddable", "uiActions"], "optionalPlugins": [], - "extraPublicDirs": ["public/todo", "public/hello_world", "public/todo/todo_ref_embeddable"] + "extraPublicDirs": ["public/todo", "public/hello_world", "public/todo/todo_ref_embeddable"], + "requiredBundles": ["kibanaReact"] } diff --git a/examples/embeddable_examples/public/book/book_component.tsx b/examples/embeddable_examples/public/book/book_component.tsx new file mode 100644 index 0000000000000..064e13c131a0a --- /dev/null +++ b/examples/embeddable_examples/public/book/book_component.tsx @@ -0,0 +1,90 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { EuiFlexItem, EuiFlexGroup, EuiIcon } from '@elastic/eui'; + +import { EuiText } from '@elastic/eui'; +import { EuiFlexGrid } from '@elastic/eui'; +import { withEmbeddableSubscription } from '../../../../src/plugins/embeddable/public'; +import { BookEmbeddableInput, BookEmbeddableOutput, BookEmbeddable } from './book_embeddable'; + +interface Props { + input: BookEmbeddableInput; + output: BookEmbeddableOutput; + embeddable: BookEmbeddable; +} + +function wrapSearchTerms(task?: string, search?: string) { + if (!search || !task) return task; + const parts = task.split(new RegExp(`(${search})`, 'g')); + return parts.map((part, i) => + part === search ? ( + + {part} + + ) : ( + part + ) + ); +} + +export function BookEmbeddableComponentInner({ input: { search }, output: { attributes } }: Props) { + const title = attributes?.title; + const author = attributes?.author; + const readIt = attributes?.readIt; + + return ( + + + + {title ? ( + + +

{wrapSearchTerms(title, search)},

+
+
+ ) : null} + {author ? ( + + +
-{wrapSearchTerms(author, search)}
+
+
+ ) : null} + {readIt ? ( + + + + ) : ( + + + + )} +
+
+
+ ); +} + +export const BookEmbeddableComponent = withEmbeddableSubscription< + BookEmbeddableInput, + BookEmbeddableOutput, + BookEmbeddable, + {} +>(BookEmbeddableComponentInner); diff --git a/examples/embeddable_examples/public/book/book_embeddable.tsx b/examples/embeddable_examples/public/book/book_embeddable.tsx new file mode 100644 index 0000000000000..d49bd3280d97d --- /dev/null +++ b/examples/embeddable_examples/public/book/book_embeddable.tsx @@ -0,0 +1,123 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import ReactDOM from 'react-dom'; +import { Subscription } from 'rxjs'; +import { + Embeddable, + EmbeddableInput, + IContainer, + EmbeddableOutput, + SavedObjectEmbeddableInput, + AttributeService, +} from '../../../../src/plugins/embeddable/public'; +import { BookSavedObjectAttributes } from '../../common'; +import { BookEmbeddableComponent } from './book_component'; + +export const BOOK_EMBEDDABLE = 'book'; +export type BookEmbeddableInput = BookByValueInput | BookByReferenceInput; +export interface BookEmbeddableOutput extends EmbeddableOutput { + hasMatch: boolean; + attributes: BookSavedObjectAttributes; +} + +interface BookInheritedInput extends EmbeddableInput { + search?: string; +} + +export type BookByValueInput = { attributes: BookSavedObjectAttributes } & BookInheritedInput; +export type BookByReferenceInput = SavedObjectEmbeddableInput & BookInheritedInput; + +/** + * Returns whether any attributes contain the search string. If search is empty, true is returned. If + * there are no savedAttributes, false is returned. + * @param search - the search string + * @param savedAttributes - the saved object attributes for the saved object with id `input.savedObjectId` + */ +function getHasMatch(search?: string, savedAttributes?: BookSavedObjectAttributes): boolean { + if (!search) return true; + if (!savedAttributes) return false; + return Boolean( + (savedAttributes.author && savedAttributes.author.match(search)) || + (savedAttributes.title && savedAttributes.title.match(search)) + ); +} + +export class BookEmbeddable extends Embeddable { + public readonly type = BOOK_EMBEDDABLE; + private subscription: Subscription; + private node?: HTMLElement; + private savedObjectId?: string; + private attributes?: BookSavedObjectAttributes; + + constructor( + initialInput: BookEmbeddableInput, + private attributeService: AttributeService< + BookSavedObjectAttributes, + BookByValueInput, + BookByReferenceInput + >, + { + parent, + }: { + parent?: IContainer; + } + ) { + super(initialInput, {} as BookEmbeddableOutput, parent); + + this.subscription = this.getInput$().subscribe(async () => { + const savedObjectId = (this.getInput() as BookByReferenceInput).savedObjectId; + const attributes = (this.getInput() as BookByValueInput).attributes; + if (this.attributes !== attributes || this.savedObjectId !== savedObjectId) { + this.savedObjectId = savedObjectId; + this.reload(); + } else { + this.updateOutput({ + attributes: this.attributes, + hasMatch: getHasMatch(this.input.search, this.attributes), + }); + } + }); + } + + public render(node: HTMLElement) { + if (this.node) { + ReactDOM.unmountComponentAtNode(this.node); + } + this.node = node; + ReactDOM.render(, node); + } + + public async reload() { + this.attributes = await this.attributeService.unwrapAttributes(this.input); + + this.updateOutput({ + attributes: this.attributes, + hasMatch: getHasMatch(this.input.search, this.attributes), + }); + } + + public destroy() { + super.destroy(); + this.subscription.unsubscribe(); + if (this.node) { + ReactDOM.unmountComponentAtNode(this.node); + } + } +} diff --git a/examples/embeddable_examples/public/book/book_embeddable_factory.tsx b/examples/embeddable_examples/public/book/book_embeddable_factory.tsx new file mode 100644 index 0000000000000..f4a32fb498a2d --- /dev/null +++ b/examples/embeddable_examples/public/book/book_embeddable_factory.tsx @@ -0,0 +1,127 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { BookSavedObjectAttributes, BOOK_SAVED_OBJECT } from '../../common'; +import { toMountPoint } from '../../../../src/plugins/kibana_react/public'; +import { + EmbeddableFactoryDefinition, + EmbeddableStart, + IContainer, + AttributeService, + EmbeddableFactory, +} from '../../../../src/plugins/embeddable/public'; +import { + BookEmbeddable, + BOOK_EMBEDDABLE, + BookEmbeddableInput, + BookEmbeddableOutput, + BookByValueInput, + BookByReferenceInput, +} from './book_embeddable'; +import { CreateEditBookComponent } from './create_edit_book_component'; +import { OverlayStart } from '../../../../src/core/public'; + +interface StartServices { + getAttributeService: EmbeddableStart['getAttributeService']; + openModal: OverlayStart['openModal']; +} + +export type BookEmbeddableFactory = EmbeddableFactory< + BookEmbeddableInput, + BookEmbeddableOutput, + BookEmbeddable, + BookSavedObjectAttributes +>; + +export class BookEmbeddableFactoryDefinition + implements + EmbeddableFactoryDefinition< + BookEmbeddableInput, + BookEmbeddableOutput, + BookEmbeddable, + BookSavedObjectAttributes + > { + public readonly type = BOOK_EMBEDDABLE; + public savedObjectMetaData = { + name: 'Book', + includeFields: ['title', 'author', 'readIt'], + type: BOOK_SAVED_OBJECT, + getIconForSavedObject: () => 'pencil', + }; + + private attributeService?: AttributeService< + BookSavedObjectAttributes, + BookByValueInput, + BookByReferenceInput + >; + + constructor(private getStartServices: () => Promise) {} + + public async isEditable() { + return true; + } + + public async create(input: BookEmbeddableInput, parent?: IContainer) { + return new BookEmbeddable(input, await this.getAttributeService(), { + parent, + }); + } + + public getDisplayName() { + return i18n.translate('embeddableExamples.book.displayName', { + defaultMessage: 'Book', + }); + } + + public async getExplicitInput(): Promise> { + const { openModal } = await this.getStartServices(); + return new Promise>((resolve) => { + const onSave = async (attributes: BookSavedObjectAttributes, useRefType: boolean) => { + const wrappedAttributes = (await this.getAttributeService()).wrapAttributes( + attributes, + useRefType + ); + resolve(wrappedAttributes); + }; + const overlay = openModal( + toMountPoint( + { + onSave(attributes, useRefType); + overlay.close(); + }} + /> + ) + ); + }); + } + + private async getAttributeService() { + if (!this.attributeService) { + this.attributeService = await (await this.getStartServices()).getAttributeService< + BookSavedObjectAttributes, + BookByValueInput, + BookByReferenceInput + >(this.type); + } + return this.attributeService; + } +} diff --git a/examples/embeddable_examples/public/book/create_edit_book_component.tsx b/examples/embeddable_examples/public/book/create_edit_book_component.tsx new file mode 100644 index 0000000000000..7e2d3cb9d88ab --- /dev/null +++ b/examples/embeddable_examples/public/book/create_edit_book_component.tsx @@ -0,0 +1,88 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React, { useState } from 'react'; +import { EuiModalBody, EuiCheckbox } from '@elastic/eui'; +import { EuiFieldText } from '@elastic/eui'; +import { EuiButton } from '@elastic/eui'; +import { EuiModalFooter } from '@elastic/eui'; +import { EuiModalHeader } from '@elastic/eui'; +import { EuiFormRow } from '@elastic/eui'; +import { BookSavedObjectAttributes } from '../../common'; + +export function CreateEditBookComponent({ + savedObjectId, + attributes, + onSave, +}: { + savedObjectId?: string; + attributes?: BookSavedObjectAttributes; + onSave: (attributes: BookSavedObjectAttributes, useRefType: boolean) => void; +}) { + const [title, setTitle] = useState(attributes?.title ?? ''); + const [author, setAuthor] = useState(attributes?.author ?? ''); + const [readIt, setReadIt] = useState(attributes?.readIt ?? false); + return ( + + +

{`${savedObjectId ? 'Create new ' : 'Edit '}`}

+
+ + + setTitle(e.target.value)} + /> + + + setAuthor(e.target.value)} + /> + + + setReadIt(event.target.checked)} + /> + + + + onSave({ title, author, readIt }, false)} + > + {savedObjectId ? 'Unlink from library item' : 'Save and Return'} + + onSave({ title, author, readIt }, true)} + > + {savedObjectId ? 'Update library item' : 'Save to library'} + + +
+ ); +} diff --git a/examples/embeddable_examples/public/book/edit_book_action.tsx b/examples/embeddable_examples/public/book/edit_book_action.tsx new file mode 100644 index 0000000000000..222f70e0be60f --- /dev/null +++ b/examples/embeddable_examples/public/book/edit_book_action.tsx @@ -0,0 +1,93 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { OverlayStart } from 'kibana/public'; +import { i18n } from '@kbn/i18n'; +import { BookSavedObjectAttributes, BOOK_SAVED_OBJECT } from '../../common'; +import { createAction } from '../../../../src/plugins/ui_actions/public'; +import { toMountPoint } from '../../../../src/plugins/kibana_react/public'; +import { + ViewMode, + EmbeddableStart, + SavedObjectEmbeddableInput, +} from '../../../../src/plugins/embeddable/public'; +import { + BookEmbeddable, + BOOK_EMBEDDABLE, + BookByReferenceInput, + BookByValueInput, +} from './book_embeddable'; +import { CreateEditBookComponent } from './create_edit_book_component'; + +interface StartServices { + openModal: OverlayStart['openModal']; + getAttributeService: EmbeddableStart['getAttributeService']; +} + +interface ActionContext { + embeddable: BookEmbeddable; +} + +export const ACTION_EDIT_BOOK = 'ACTION_EDIT_BOOK'; + +export const createEditBookAction = (getStartServices: () => Promise) => + createAction({ + getDisplayName: () => + i18n.translate('embeddableExamples.book.edit', { defaultMessage: 'Edit Book' }), + type: ACTION_EDIT_BOOK, + order: 100, + getIconType: () => 'documents', + isCompatible: async ({ embeddable }: ActionContext) => { + return ( + embeddable.type === BOOK_EMBEDDABLE && embeddable.getInput().viewMode === ViewMode.EDIT + ); + }, + execute: async ({ embeddable }: ActionContext) => { + const { openModal, getAttributeService } = await getStartServices(); + const attributeService = getAttributeService< + BookSavedObjectAttributes, + BookByValueInput, + BookByReferenceInput + >(BOOK_SAVED_OBJECT); + const onSave = async (attributes: BookSavedObjectAttributes, useRefType: boolean) => { + const newInput = await attributeService.wrapAttributes(attributes, useRefType, embeddable); + if (!useRefType && (embeddable.getInput() as SavedObjectEmbeddableInput).savedObjectId) { + // Remove the savedObejctId when un-linking + newInput.savedObjectId = null; + } + embeddable.updateInput(newInput); + if (useRefType) { + // Ensures that any duplicate embeddables also register the changes. This mirrors the behavior of going back and forth between apps + embeddable.getRoot().reload(); + } + }; + const overlay = openModal( + toMountPoint( + { + overlay.close(); + onSave(attributes, useRefType); + }} + /> + ) + ); + }, + }); diff --git a/examples/embeddable_examples/public/book/index.ts b/examples/embeddable_examples/public/book/index.ts new file mode 100644 index 0000000000000..46f44926e2152 --- /dev/null +++ b/examples/embeddable_examples/public/book/index.ts @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './book_embeddable'; +export * from './book_embeddable_factory'; diff --git a/examples/embeddable_examples/public/create_sample_data.ts b/examples/embeddable_examples/public/create_sample_data.ts index bd5ade18aa91e..d598c32a182fe 100644 --- a/examples/embeddable_examples/public/create_sample_data.ts +++ b/examples/embeddable_examples/public/create_sample_data.ts @@ -18,9 +18,9 @@ */ import { SavedObjectsClientContract } from 'kibana/public'; -import { TodoSavedObjectAttributes } from '../common'; +import { TodoSavedObjectAttributes, BookSavedObjectAttributes, BOOK_SAVED_OBJECT } from '../common'; -export async function createSampleData(client: SavedObjectsClientContract) { +export async function createSampleData(client: SavedObjectsClientContract, overwrite = true) { await client.create( 'todo', { @@ -30,7 +30,20 @@ export async function createSampleData(client: SavedObjectsClientContract) { }, { id: 'sample-todo-saved-object', - overwrite: true, + overwrite, + } + ); + + await client.create( + BOOK_SAVED_OBJECT, + { + title: 'Pillars of the Earth', + author: 'Ken Follett', + readIt: true, + }, + { + id: 'sample-book-saved-object', + overwrite, } ); } diff --git a/examples/embeddable_examples/public/index.ts b/examples/embeddable_examples/public/index.ts index ec007f7c626f0..86f50f2b6e114 100644 --- a/examples/embeddable_examples/public/index.ts +++ b/examples/embeddable_examples/public/index.ts @@ -26,6 +26,8 @@ export { export { ListContainer, LIST_CONTAINER, ListContainerFactory } from './list_container'; export { TODO_EMBEDDABLE, TodoEmbeddableFactory } from './todo'; +export { BOOK_EMBEDDABLE } from './book'; + import { EmbeddableExamplesPlugin } from './plugin'; export { diff --git a/examples/embeddable_examples/public/plugin.ts b/examples/embeddable_examples/public/plugin.ts index d65ca1e8e7e8d..95f4f5b41e198 100644 --- a/examples/embeddable_examples/public/plugin.ts +++ b/examples/embeddable_examples/public/plugin.ts @@ -17,14 +17,19 @@ * under the License. */ -import { EmbeddableSetup, EmbeddableStart } from '../../../src/plugins/embeddable/public'; -import { CoreSetup, CoreStart, Plugin } from '../../../src/core/public'; import { + EmbeddableSetup, + EmbeddableStart, + CONTEXT_MENU_TRIGGER, +} from '../../../src/plugins/embeddable/public'; +import { Plugin, CoreSetup, CoreStart } from '../../../src/core/public'; +import { + HelloWorldEmbeddableFactory, HELLO_WORLD_EMBEDDABLE, HelloWorldEmbeddableFactoryDefinition, - HelloWorldEmbeddableFactory, } from './hello_world'; import { TODO_EMBEDDABLE, TodoEmbeddableFactory, TodoEmbeddableFactoryDefinition } from './todo'; + import { MULTI_TASK_TODO_EMBEDDABLE, MultiTaskTodoEmbeddableFactory, @@ -46,9 +51,17 @@ import { TodoRefEmbeddableFactory, TodoRefEmbeddableFactoryDefinition, } from './todo/todo_ref_embeddable_factory'; +import { ACTION_EDIT_BOOK, createEditBookAction } from './book/edit_book_action'; +import { BookEmbeddable, BOOK_EMBEDDABLE } from './book/book_embeddable'; +import { + BookEmbeddableFactory, + BookEmbeddableFactoryDefinition, +} from './book/book_embeddable_factory'; +import { UiActionsStart } from '../../../src/plugins/ui_actions/public'; export interface EmbeddableExamplesSetupDependencies { embeddable: EmbeddableSetup; + uiActions: UiActionsStart; } export interface EmbeddableExamplesStartDependencies { @@ -62,6 +75,7 @@ interface ExampleEmbeddableFactories { getListContainerEmbeddableFactory: () => ListContainerFactory; getTodoEmbeddableFactory: () => TodoEmbeddableFactory; getTodoRefEmbeddableFactory: () => TodoRefEmbeddableFactory; + getBookEmbeddableFactory: () => BookEmbeddableFactory; } export interface EmbeddableExamplesStart { @@ -69,6 +83,12 @@ export interface EmbeddableExamplesStart { factories: ExampleEmbeddableFactories; } +declare module '../../../src/plugins/ui_actions/public' { + export interface ActionContextMapping { + [ACTION_EDIT_BOOK]: { embeddable: BookEmbeddable }; + } +} + export class EmbeddableExamplesPlugin implements Plugin< @@ -121,6 +141,20 @@ export class EmbeddableExamplesPlugin getEmbeddableFactory: (await core.getStartServices())[1].embeddable.getEmbeddableFactory, })) ); + this.exampleEmbeddableFactories.getBookEmbeddableFactory = deps.embeddable.registerEmbeddableFactory( + BOOK_EMBEDDABLE, + new BookEmbeddableFactoryDefinition(async () => ({ + getAttributeService: (await core.getStartServices())[1].embeddable.getAttributeService, + openModal: (await core.getStartServices())[0].overlays.openModal, + })) + ); + + const editBookAction = createEditBookAction(async () => ({ + getAttributeService: (await core.getStartServices())[1].embeddable.getAttributeService, + openModal: (await core.getStartServices())[0].overlays.openModal, + })); + deps.uiActions.registerAction(editBookAction); + deps.uiActions.attachAction(CONTEXT_MENU_TRIGGER, editBookAction.id); } public start( diff --git a/test/functional/config.ie.js b/examples/embeddable_examples/server/book_saved_object.ts similarity index 52% rename from test/functional/config.ie.js rename to examples/embeddable_examples/server/book_saved_object.ts index bc47ce707003e..f0aca57f7925f 100644 --- a/test/functional/config.ie.js +++ b/examples/embeddable_examples/server/book_saved_object.ts @@ -17,36 +17,24 @@ * under the License. */ -export default async function ({ readConfigFile }) { - const defaultConfig = await readConfigFile(require.resolve('./config')); +import { SavedObjectsType } from 'kibana/server'; - return { - ...defaultConfig.getAll(), - - browser: { - type: 'ie', - }, - - junit: { - reportName: 'Internet Explorer UI Functional Tests', - }, - - uiSettings: { - defaults: { - 'accessibility:disableAnimations': true, - 'dateFormat:tz': 'UTC', - 'state:storeInSessionStorage': true, - 'notifications:lifetime:info': 10000, +export const bookSavedObject: SavedObjectsType = { + name: 'book', + hidden: false, + namespaceType: 'agnostic', + mappings: { + properties: { + title: { + type: 'keyword', + }, + author: { + type: 'keyword', + }, + readIt: { + type: 'boolean', }, }, - - kbnTestServer: { - ...defaultConfig.get('kbnTestServer'), - serverArgs: [ - ...defaultConfig.get('kbnTestServer.serverArgs'), - '--csp.strict=false', - '--telemetry.optIn=false', - ], - }, - }; -} + }, + migrations: {}, +}; diff --git a/examples/embeddable_examples/server/plugin.ts b/examples/embeddable_examples/server/plugin.ts index d956b834d0d3c..1308ac9e0fc5e 100644 --- a/examples/embeddable_examples/server/plugin.ts +++ b/examples/embeddable_examples/server/plugin.ts @@ -19,10 +19,12 @@ import { Plugin, CoreSetup, CoreStart } from 'kibana/server'; import { todoSavedObject } from './todo_saved_object'; +import { bookSavedObject } from './book_saved_object'; export class EmbeddableExamplesPlugin implements Plugin { public setup(core: CoreSetup) { core.savedObjects.registerType(todoSavedObject); + core.savedObjects.registerType(bookSavedObject); } public start(core: CoreStart) {} diff --git a/examples/embeddable_explorer/public/embeddable_panel_example.tsx b/examples/embeddable_explorer/public/embeddable_panel_example.tsx index b2807f9a4c346..ca9675bb7f5a1 100644 --- a/examples/embeddable_explorer/public/embeddable_panel_example.tsx +++ b/examples/embeddable_explorer/public/embeddable_panel_example.tsx @@ -33,6 +33,7 @@ import { EmbeddableStart, IEmbeddable } from '../../../src/plugins/embeddable/pu import { HELLO_WORLD_EMBEDDABLE, TODO_EMBEDDABLE, + BOOK_EMBEDDABLE, MULTI_TASK_TODO_EMBEDDABLE, SearchableListContainerFactory, } from '../../embeddable_examples/public'; @@ -72,6 +73,35 @@ export function EmbeddablePanelExample({ embeddableServices, searchListContainer tasks: ['Go to school', 'Watch planet earth', 'Read the encyclopedia'], }, }, + '4': { + type: BOOK_EMBEDDABLE, + explicitInput: { + id: '4', + savedObjectId: 'sample-book-saved-object', + }, + }, + '5': { + type: BOOK_EMBEDDABLE, + explicitInput: { + id: '5', + attributes: { + title: 'The Sympathizer', + author: 'Viet Thanh Nguyen', + readIt: true, + }, + }, + }, + '6': { + type: BOOK_EMBEDDABLE, + explicitInput: { + id: '6', + attributes: { + title: 'The Hobbit', + author: 'J.R.R. Tolkien', + readIt: false, + }, + }, + }, }, }; diff --git a/examples/state_containers_examples/kibana.json b/examples/state_containers_examples/kibana.json index 66da207cb4e77..58346af8f1d19 100644 --- a/examples/state_containers_examples/kibana.json +++ b/examples/state_containers_examples/kibana.json @@ -5,5 +5,6 @@ "server": true, "ui": true, "requiredPlugins": ["navigation", "data", "developerExamples"], - "optionalPlugins": [] + "optionalPlugins": [], + "requiredBundles": ["kibanaUtils", "kibanaReact"] } diff --git a/examples/ui_action_examples/kibana.json b/examples/ui_action_examples/kibana.json index cd12442daf61c..0e0b6b6830b95 100644 --- a/examples/ui_action_examples/kibana.json +++ b/examples/ui_action_examples/kibana.json @@ -5,5 +5,6 @@ "server": false, "ui": true, "requiredPlugins": ["uiActions"], - "optionalPlugins": [] + "optionalPlugins": [], + "requiredBundles": ["kibanaReact"] } diff --git a/examples/ui_actions_explorer/kibana.json b/examples/ui_actions_explorer/kibana.json index f57072e89b06d..0a55e60374710 100644 --- a/examples/ui_actions_explorer/kibana.json +++ b/examples/ui_actions_explorer/kibana.json @@ -5,5 +5,6 @@ "server": false, "ui": true, "requiredPlugins": ["uiActions", "uiActionsExamples", "developerExamples"], - "optionalPlugins": [] + "optionalPlugins": [], + "requiredBundles": ["kibanaReact"] } diff --git a/package.json b/package.json index 1a497a2ec8b10..a45f240ce13af 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,7 @@ "@elastic/datemath": "5.0.3", "@elastic/elasticsearch": "7.8.0", "@elastic/ems-client": "7.9.3", - "@elastic/eui": "24.1.0", + "@elastic/eui": "26.3.1", "@elastic/filesaver": "1.1.2", "@elastic/good": "8.1.1-kibana2", "@elastic/numeral": "^2.5.0", diff --git a/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/kibana.json b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/kibana.json index 20c8046daa65e..33f53e336598d 100644 --- a/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/kibana.json +++ b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/kibana.json @@ -1,4 +1,5 @@ { "id": "bar", - "ui": true + "ui": true, + "requiredBundles": ["foo"] } diff --git a/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/_other_styles.scss b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/_other_styles.scss new file mode 100644 index 0000000000000..2c1b9562b9567 --- /dev/null +++ b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/_other_styles.scss @@ -0,0 +1,3 @@ +p { + background-color: rebeccapurple; +} diff --git a/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/styles.scss b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/styles.scss index e71a2d485a2f8..1dc7bbe9daeb0 100644 --- a/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/styles.scss +++ b/packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/public/legacy/styles.scss @@ -1,3 +1,5 @@ +@import "./other_styles.scss"; + body { width: $globalStyleConstant; background-image: url("ui/icon.svg"); diff --git a/packages/kbn-optimizer/src/cli.ts b/packages/kbn-optimizer/src/cli.ts index 0916f12a7110d..9d3f4b88a258f 100644 --- a/packages/kbn-optimizer/src/cli.ts +++ b/packages/kbn-optimizer/src/cli.ts @@ -87,6 +87,11 @@ run( throw createFlagError('expected --report-stats to have no value'); } + const filter = typeof flags.filter === 'string' ? [flags.filter] : flags.filter; + if (!Array.isArray(filter) || !filter.every((f) => typeof f === 'string')) { + throw createFlagError('expected --filter to be one or more strings'); + } + const config = OptimizerConfig.create({ repoRoot: REPO_ROOT, watch, @@ -99,6 +104,7 @@ run( extraPluginScanDirs, inspectWorkers, includeCoreBundle, + filter, }); let update$ = runOptimizer(config); @@ -128,12 +134,13 @@ run( 'inspect-workers', 'report-stats', ], - string: ['workers', 'scan-dir'], + string: ['workers', 'scan-dir', 'filter'], default: { core: true, examples: true, cache: true, 'inspect-workers': true, + filter: [], }, help: ` --watch run the optimizer in watch mode @@ -142,6 +149,7 @@ run( --profile profile the webpack builds and write stats.json files to build outputs --no-core disable generating the core bundle --no-cache disable the cache + --filter comma-separated list of bundle id filters, results from multiple flags are merged, * and ! are supported --no-examples don't build the example plugins --dist create bundles that are suitable for inclusion in the Kibana distributable --scan-dir add a directory to the list of directories scanned for plugins (specify as many times as necessary) diff --git a/packages/kbn-optimizer/src/common/bundle.test.ts b/packages/kbn-optimizer/src/common/bundle.test.ts index b209bbca25ac4..6197a08485854 100644 --- a/packages/kbn-optimizer/src/common/bundle.test.ts +++ b/packages/kbn-optimizer/src/common/bundle.test.ts @@ -50,6 +50,7 @@ it('creates cache keys', () => { "spec": Object { "contextDir": "/foo/bar", "id": "bar", + "manifestPath": undefined, "outputDir": "/foo/bar/target", "publicDirNames": Array [ "public", @@ -85,6 +86,7 @@ it('parses bundles from JSON specs', () => { }, "contextDir": "/foo/bar", "id": "bar", + "manifestPath": undefined, "outputDir": "/foo/bar/target", "publicDirNames": Array [ "public", diff --git a/packages/kbn-optimizer/src/common/bundle.ts b/packages/kbn-optimizer/src/common/bundle.ts index 80af94c30f8da..a354da7a21521 100644 --- a/packages/kbn-optimizer/src/common/bundle.ts +++ b/packages/kbn-optimizer/src/common/bundle.ts @@ -18,6 +18,7 @@ */ import Path from 'path'; +import Fs from 'fs'; import { BundleCache } from './bundle_cache'; import { UnknownVals } from './ts_helpers'; @@ -25,6 +26,11 @@ import { includes, ascending, entriesToObject } from './array_helpers'; const VALID_BUNDLE_TYPES = ['plugin' as const, 'entry' as const]; +const DEFAULT_IMPLICIT_BUNDLE_DEPS = ['core']; + +const isStringArray = (input: any): input is string[] => + Array.isArray(input) && input.every((x) => typeof x === 'string'); + export interface BundleSpec { readonly type: typeof VALID_BUNDLE_TYPES[0]; /** Unique id for this bundle */ @@ -37,6 +43,8 @@ export interface BundleSpec { readonly sourceRoot: string; /** Absolute path to the directory where output should be written */ readonly outputDir: string; + /** Absolute path to a kibana.json manifest file, if omitted we assume there are not dependenices */ + readonly manifestPath?: string; } export class Bundle { @@ -56,6 +64,12 @@ export class Bundle { public readonly sourceRoot: BundleSpec['sourceRoot']; /** Absolute path to the output directory for this bundle */ public readonly outputDir: BundleSpec['outputDir']; + /** + * Absolute path to a manifest file with "requiredBundles" which will be + * used to allow bundleRefs from this bundle to the exports of another bundle. + * Every bundle mentioned in the `requiredBundles` must be built together. + */ + public readonly manifestPath: BundleSpec['manifestPath']; public readonly cache: BundleCache; @@ -66,6 +80,7 @@ export class Bundle { this.contextDir = spec.contextDir; this.sourceRoot = spec.sourceRoot; this.outputDir = spec.outputDir; + this.manifestPath = spec.manifestPath; this.cache = new BundleCache(Path.resolve(this.outputDir, '.kbn-optimizer-cache')); } @@ -96,8 +111,54 @@ export class Bundle { contextDir: this.contextDir, sourceRoot: this.sourceRoot, outputDir: this.outputDir, + manifestPath: this.manifestPath, }; } + + readBundleDeps(): { implicit: string[]; explicit: string[] } { + if (!this.manifestPath) { + return { + implicit: [...DEFAULT_IMPLICIT_BUNDLE_DEPS], + explicit: [], + }; + } + + let json: string; + try { + json = Fs.readFileSync(this.manifestPath, 'utf8'); + } catch (error) { + if (error.code !== 'ENOENT') { + throw error; + } + + json = '{}'; + } + + let parsedManifest: { requiredPlugins?: string[]; requiredBundles?: string[] }; + try { + parsedManifest = JSON.parse(json); + } catch (error) { + throw new Error( + `unable to parse manifest at [${this.manifestPath}], error: [${error.message}]` + ); + } + + if (typeof parsedManifest === 'object' && parsedManifest) { + const explicit = parsedManifest.requiredBundles || []; + const implicit = [...DEFAULT_IMPLICIT_BUNDLE_DEPS, ...(parsedManifest.requiredPlugins || [])]; + + if (isStringArray(explicit) && isStringArray(implicit)) { + return { + explicit, + implicit, + }; + } + } + + throw new Error( + `Expected "requiredBundles" and "requiredPlugins" in manifest file [${this.manifestPath}] to be arrays of strings` + ); + } } /** @@ -152,6 +213,13 @@ export function parseBundles(json: string) { throw new Error('`bundles[]` must have an absolute path `outputDir` property'); } + const { manifestPath } = spec; + if (manifestPath !== undefined) { + if (!(typeof manifestPath === 'string' && Path.isAbsolute(manifestPath))) { + throw new Error('`bundles[]` must have an absolute path `manifestPath` property'); + } + } + return new Bundle({ type, id, @@ -159,6 +227,7 @@ export function parseBundles(json: string) { contextDir, sourceRoot, outputDir, + manifestPath, }); } ); diff --git a/packages/kbn-optimizer/src/common/bundle_cache.ts b/packages/kbn-optimizer/src/common/bundle_cache.ts index 5ae3e4c28a201..7607e270b5b4f 100644 --- a/packages/kbn-optimizer/src/common/bundle_cache.ts +++ b/packages/kbn-optimizer/src/common/bundle_cache.ts @@ -24,6 +24,7 @@ export interface State { optimizerCacheKey?: unknown; cacheKey?: unknown; moduleCount?: number; + workUnits?: number; files?: string[]; bundleRefExportIds?: string[]; } @@ -96,6 +97,10 @@ export class BundleCache { return this.get().cacheKey; } + public getWorkUnits() { + return this.get().workUnits; + } + public getOptimizerCacheKey() { return this.get().optimizerCacheKey; } diff --git a/packages/kbn-optimizer/src/common/bundle_refs.ts b/packages/kbn-optimizer/src/common/bundle_refs.ts index a5c60f2031c0b..85731f32f8991 100644 --- a/packages/kbn-optimizer/src/common/bundle_refs.ts +++ b/packages/kbn-optimizer/src/common/bundle_refs.ts @@ -114,6 +114,10 @@ export class BundleRefs { constructor(private readonly refs: BundleRef[]) {} + public forBundleIds(bundleIds: string[]) { + return this.refs.filter((r) => bundleIds.includes(r.bundleId)); + } + public filterByExportIds(exportIds: string[]) { return this.refs.filter((r) => exportIds.includes(r.exportId)); } diff --git a/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap b/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap index 211cfac3806ad..c52873ab7ec20 100644 --- a/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap +++ b/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap @@ -10,6 +10,7 @@ OptimizerConfig { }, "contextDir": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar, "id": "bar", + "manifestPath": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/kibana.json, "outputDir": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/target/public, "publicDirNames": Array [ "public", @@ -24,6 +25,7 @@ OptimizerConfig { }, "contextDir": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo, "id": "foo", + "manifestPath": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo/kibana.json, "outputDir": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo/target/public, "publicDirNames": Array [ "public", @@ -42,18 +44,21 @@ OptimizerConfig { "extraPublicDirs": Array [], "id": "bar", "isUiPlugin": true, + "manifestPath": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/kibana.json, }, Object { "directory": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo, "extraPublicDirs": Array [], "id": "foo", "isUiPlugin": true, + "manifestPath": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo/kibana.json, }, Object { "directory": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/nested/baz, "extraPublicDirs": Array [], "id": "baz", "isUiPlugin": false, + "manifestPath": /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/nested/baz/kibana.json, }, ], "profileWebpack": false, @@ -66,7 +71,7 @@ OptimizerConfig { } `; -exports[`prepares assets for distribution: bar bundle 1`] = `"(function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId]){return installedModules[moduleId].exports}var module=installedModules[moduleId]={i:moduleId,l:false,exports:{}};modules[moduleId].call(module.exports,module,module.exports,__webpack_require__);module.l=true;return module.exports}__webpack_require__.m=modules;__webpack_require__.c=installedModules;__webpack_require__.d=function(exports,name,getter){if(!__webpack_require__.o(exports,name)){Object.defineProperty(exports,name,{enumerable:true,get:getter})}};__webpack_require__.r=function(exports){if(typeof Symbol!==\\"undefined\\"&&Symbol.toStringTag){Object.defineProperty(exports,Symbol.toStringTag,{value:\\"Module\\"})}Object.defineProperty(exports,\\"__esModule\\",{value:true})};__webpack_require__.t=function(value,mode){if(mode&1)value=__webpack_require__(value);if(mode&8)return value;if(mode&4&&typeof value===\\"object\\"&&value&&value.__esModule)return value;var ns=Object.create(null);__webpack_require__.r(ns);Object.defineProperty(ns,\\"default\\",{enumerable:true,value:value});if(mode&2&&typeof value!=\\"string\\")for(var key in value)__webpack_require__.d(ns,key,function(key){return value[key]}.bind(null,key));return ns};__webpack_require__.n=function(module){var getter=module&&module.__esModule?function getDefault(){return module[\\"default\\"]}:function getModuleExports(){return module};__webpack_require__.d(getter,\\"a\\",getter);return getter};__webpack_require__.o=function(object,property){return Object.prototype.hasOwnProperty.call(object,property)};__webpack_require__.p=\\"\\";return __webpack_require__(__webpack_require__.s=5)})([function(module,exports,__webpack_require__){\\"use strict\\";var isOldIE=function isOldIE(){var memo;return function memorize(){if(typeof memo===\\"undefined\\"){memo=Boolean(window&&document&&document.all&&!window.atob)}return memo}}();var getTarget=function getTarget(){var memo={};return function memorize(target){if(typeof memo[target]===\\"undefined\\"){var styleTarget=document.querySelector(target);if(window.HTMLIFrameElement&&styleTarget instanceof window.HTMLIFrameElement){try{styleTarget=styleTarget.contentDocument.head}catch(e){styleTarget=null}}memo[target]=styleTarget}return memo[target]}}();var stylesInDom=[];function getIndexByIdentifier(identifier){var result=-1;for(var i=0;i { expect(foo.cache.getModuleCount()).toBe(6); expect(foo.cache.getReferencedFiles()).toMatchInlineSnapshot(` Array [ + /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo/kibana.json, /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo/public/async_import.ts, /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo/public/ext.ts, /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/foo/public/index.ts, @@ -160,12 +161,17 @@ it('builds expected bundles, saves bundle counts to metadata', async () => { Array [ /node_modules/css-loader/package.json, /node_modules/style-loader/package.json, + /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/kibana.json, /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/public/index.scss, /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/public/index.ts, + /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/public/legacy/_other_styles.scss, /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/public/legacy/styles.scss, /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/plugins/bar/public/lib.ts, /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/src/legacy/ui/public/icon.svg, + /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/src/legacy/ui/public/styles/_globals_v7dark.scss, + /packages/kbn-optimizer/src/__fixtures__/__tmp__/mock_repo/src/legacy/ui/public/styles/_globals_v7light.scss, /packages/kbn-optimizer/target/worker/entry_point_creator.js, + /packages/kbn-optimizer/target/worker/postcss.config.js, /packages/kbn-ui-shared-deps/public_path_module_creator.js, ] `); diff --git a/packages/kbn-optimizer/src/log_optimizer_state.ts b/packages/kbn-optimizer/src/log_optimizer_state.ts index 23767be610da4..20d98f74dbe86 100644 --- a/packages/kbn-optimizer/src/log_optimizer_state.ts +++ b/packages/kbn-optimizer/src/log_optimizer_state.ts @@ -54,12 +54,18 @@ export function logOptimizerState(log: ToolingLog, config: OptimizerConfig) { if (event?.type === 'worker started') { let moduleCount = 0; + let workUnits = 0; for (const bundle of event.bundles) { moduleCount += bundle.cache.getModuleCount() ?? NaN; + workUnits += bundle.cache.getWorkUnits() ?? NaN; } - const mcString = isFinite(moduleCount) ? String(moduleCount) : '?'; - const bcString = String(event.bundles.length); - log.info(`starting worker [${bcString} bundles, ${mcString} modules]`); + + log.info( + `starting worker [${event.bundles.length} ${ + event.bundles.length === 1 ? 'bundle' : 'bundles' + }]` + ); + log.debug(`modules [${moduleCount}] work units [${workUnits}]`); } if (state.phase === 'reallocating') { diff --git a/packages/kbn-optimizer/src/optimizer/assign_bundles_to_workers.test.ts b/packages/kbn-optimizer/src/optimizer/assign_bundles_to_workers.test.ts index ca50a49e26913..5443a88eb1a63 100644 --- a/packages/kbn-optimizer/src/optimizer/assign_bundles_to_workers.test.ts +++ b/packages/kbn-optimizer/src/optimizer/assign_bundles_to_workers.test.ts @@ -23,11 +23,11 @@ import { Bundle } from '../common'; import { assignBundlesToWorkers, Assignments } from './assign_bundles_to_workers'; -const hasModuleCount = (b: Bundle) => b.cache.getModuleCount() !== undefined; -const noModuleCount = (b: Bundle) => b.cache.getModuleCount() === undefined; +const hasWorkUnits = (b: Bundle) => b.cache.getWorkUnits() !== undefined; +const noWorkUnits = (b: Bundle) => b.cache.getWorkUnits() === undefined; const summarizeBundles = (w: Assignments) => [ - w.moduleCount ? `${w.moduleCount} known modules` : '', + w.workUnits ? `${w.workUnits} work units` : '', w.newBundles ? `${w.newBundles} new bundles` : '', ] .filter(Boolean) @@ -42,15 +42,15 @@ const assertReturnVal = (workers: Assignments[]) => { expect(workers).toBeInstanceOf(Array); for (const worker of workers) { expect(worker).toEqual({ - moduleCount: expect.any(Number), + workUnits: expect.any(Number), newBundles: expect.any(Number), bundles: expect.any(Array), }); - expect(worker.bundles.filter(noModuleCount).length).toBe(worker.newBundles); + expect(worker.bundles.filter(noWorkUnits).length).toBe(worker.newBundles); expect( - worker.bundles.filter(hasModuleCount).reduce((sum, b) => sum + b.cache.getModuleCount()!, 0) - ).toBe(worker.moduleCount); + worker.bundles.filter(hasWorkUnits).reduce((sum, b) => sum + b.cache.getWorkUnits()!, 0) + ).toBe(worker.workUnits); } }; @@ -76,7 +76,7 @@ const getBundles = ({ for (let i = 1; i <= withCounts; i++) { const id = `foo${i}`; const bundle = testBundle(id); - bundle.cache.set({ moduleCount: i % 5 === 0 ? i * 10 : i }); + bundle.cache.set({ workUnits: i % 5 === 0 ? i * 10 : i }); bundles.push(bundle); } @@ -95,8 +95,8 @@ it('creates less workers if maxWorkersCount is larger than bundle count', () => expect(workers.length).toBe(2); expect(readConfigs(workers)).toMatchInlineSnapshot(` Array [ - "worker 0 (1 known modules) => foo1", - "worker 1 (2 known modules) => foo2", + "worker 0 (1 work units) => foo1", + "worker 1 (2 work units) => foo2", ] `); }); @@ -121,10 +121,10 @@ it('distributes bundles without module counts evenly after assigning modules wit assertReturnVal(workers); expect(readConfigs(workers)).toMatchInlineSnapshot(` Array [ - "worker 0 (78 known modules, 3 new bundles) => foo5,foo11,foo8,foo6,foo2,foo1,bar9,bar5,bar1", - "worker 1 (78 known modules, 3 new bundles) => foo16,foo14,foo13,foo12,foo9,foo7,foo4,foo3,bar8,bar4,bar0", - "worker 2 (100 known modules, 2 new bundles) => foo10,bar7,bar3", - "worker 3 (150 known modules, 2 new bundles) => foo15,bar6,bar2", + "worker 0 (78 work units, 3 new bundles) => foo5,foo11,foo8,foo6,foo2,foo1,bar9,bar5,bar1", + "worker 1 (78 work units, 3 new bundles) => foo16,foo14,foo13,foo12,foo9,foo7,foo4,foo3,bar8,bar4,bar0", + "worker 2 (100 work units, 2 new bundles) => foo10,bar7,bar3", + "worker 3 (150 work units, 2 new bundles) => foo15,bar6,bar2", ] `); }); @@ -135,8 +135,8 @@ it('distributes 2 bundles to workers evenly', () => { assertReturnVal(workers); expect(readConfigs(workers)).toMatchInlineSnapshot(` Array [ - "worker 0 (1 known modules) => foo1", - "worker 1 (2 known modules) => foo2", + "worker 0 (1 work units) => foo1", + "worker 1 (2 work units) => foo2", ] `); }); @@ -147,10 +147,10 @@ it('distributes 5 bundles to workers evenly', () => { assertReturnVal(workers); expect(readConfigs(workers)).toMatchInlineSnapshot(` Array [ - "worker 0 (3 known modules) => foo2,foo1", - "worker 1 (3 known modules) => foo3", - "worker 2 (4 known modules) => foo4", - "worker 3 (50 known modules) => foo5", + "worker 0 (3 work units) => foo2,foo1", + "worker 1 (3 work units) => foo3", + "worker 2 (4 work units) => foo4", + "worker 3 (50 work units) => foo5", ] `); }); @@ -161,10 +161,10 @@ it('distributes 10 bundles to workers evenly', () => { assertReturnVal(workers); expect(readConfigs(workers)).toMatchInlineSnapshot(` Array [ - "worker 0 (20 known modules) => foo9,foo6,foo4,foo1", - "worker 1 (20 known modules) => foo8,foo7,foo3,foo2", - "worker 2 (50 known modules) => foo5", - "worker 3 (100 known modules) => foo10", + "worker 0 (20 work units) => foo9,foo6,foo4,foo1", + "worker 1 (20 work units) => foo8,foo7,foo3,foo2", + "worker 2 (50 work units) => foo5", + "worker 3 (100 work units) => foo10", ] `); }); @@ -175,10 +175,10 @@ it('distributes 15 bundles to workers evenly', () => { assertReturnVal(workers); expect(readConfigs(workers)).toMatchInlineSnapshot(` Array [ - "worker 0 (70 known modules) => foo14,foo13,foo12,foo11,foo9,foo6,foo4,foo1", - "worker 1 (70 known modules) => foo5,foo8,foo7,foo3,foo2", - "worker 2 (100 known modules) => foo10", - "worker 3 (150 known modules) => foo15", + "worker 0 (70 work units) => foo14,foo13,foo12,foo11,foo9,foo6,foo4,foo1", + "worker 1 (70 work units) => foo5,foo8,foo7,foo3,foo2", + "worker 2 (100 work units) => foo10", + "worker 3 (150 work units) => foo15", ] `); }); @@ -189,10 +189,10 @@ it('distributes 20 bundles to workers evenly', () => { assertReturnVal(workers); expect(readConfigs(workers)).toMatchInlineSnapshot(` Array [ - "worker 0 (153 known modules) => foo15,foo3", - "worker 1 (153 known modules) => foo10,foo16,foo13,foo11,foo7,foo6", - "worker 2 (154 known modules) => foo5,foo19,foo18,foo17,foo14,foo12,foo9,foo8,foo4,foo2,foo1", - "worker 3 (200 known modules) => foo20", + "worker 0 (153 work units) => foo15,foo3", + "worker 1 (153 work units) => foo10,foo16,foo13,foo11,foo7,foo6", + "worker 2 (154 work units) => foo5,foo19,foo18,foo17,foo14,foo12,foo9,foo8,foo4,foo2,foo1", + "worker 3 (200 work units) => foo20", ] `); }); @@ -203,10 +203,10 @@ it('distributes 25 bundles to workers evenly', () => { assertReturnVal(workers); expect(readConfigs(workers)).toMatchInlineSnapshot(` Array [ - "worker 0 (250 known modules) => foo20,foo17,foo13,foo9,foo8,foo2,foo1", - "worker 1 (250 known modules) => foo15,foo23,foo22,foo18,foo16,foo11,foo7,foo3", - "worker 2 (250 known modules) => foo10,foo5,foo24,foo21,foo19,foo14,foo12,foo6,foo4", - "worker 3 (250 known modules) => foo25", + "worker 0 (250 work units) => foo20,foo17,foo13,foo9,foo8,foo2,foo1", + "worker 1 (250 work units) => foo15,foo23,foo22,foo18,foo16,foo11,foo7,foo3", + "worker 2 (250 work units) => foo10,foo5,foo24,foo21,foo19,foo14,foo12,foo6,foo4", + "worker 3 (250 work units) => foo25", ] `); }); @@ -217,10 +217,10 @@ it('distributes 30 bundles to workers evenly', () => { assertReturnVal(workers); expect(readConfigs(workers)).toMatchInlineSnapshot(` Array [ - "worker 0 (352 known modules) => foo30,foo22,foo14,foo11,foo4,foo1", - "worker 1 (352 known modules) => foo15,foo10,foo28,foo24,foo19,foo16,foo9,foo6", - "worker 2 (353 known modules) => foo20,foo5,foo29,foo23,foo21,foo13,foo12,foo3,foo2", - "worker 3 (353 known modules) => foo25,foo27,foo26,foo18,foo17,foo8,foo7", + "worker 0 (352 work units) => foo30,foo22,foo14,foo11,foo4,foo1", + "worker 1 (352 work units) => foo15,foo10,foo28,foo24,foo19,foo16,foo9,foo6", + "worker 2 (353 work units) => foo20,foo5,foo29,foo23,foo21,foo13,foo12,foo3,foo2", + "worker 3 (353 work units) => foo25,foo27,foo26,foo18,foo17,foo8,foo7", ] `); }); diff --git a/packages/kbn-optimizer/src/optimizer/assign_bundles_to_workers.ts b/packages/kbn-optimizer/src/optimizer/assign_bundles_to_workers.ts index e1bcb22230bf9..44a3b21c5fd47 100644 --- a/packages/kbn-optimizer/src/optimizer/assign_bundles_to_workers.ts +++ b/packages/kbn-optimizer/src/optimizer/assign_bundles_to_workers.ts @@ -20,19 +20,18 @@ import { Bundle, descending, ascending } from '../common'; // helper types used inside getWorkerConfigs so we don't have -// to calculate moduleCounts over and over - +// to calculate workUnits over and over export interface Assignments { - moduleCount: number; + workUnits: number; newBundles: number; bundles: Bundle[]; } /** assign a wrapped bundle to a worker */ const assignBundle = (worker: Assignments, bundle: Bundle) => { - const moduleCount = bundle.cache.getModuleCount(); - if (moduleCount !== undefined) { - worker.moduleCount += moduleCount; + const workUnits = bundle.cache.getWorkUnits(); + if (workUnits !== undefined) { + worker.workUnits += workUnits; } else { worker.newBundles += 1; } @@ -59,7 +58,7 @@ export function assignBundlesToWorkers(bundles: Bundle[], maxWorkerCount: number const workers: Assignments[] = []; for (let i = 0; i < workerCount; i++) { workers.push({ - moduleCount: 0, + workUnits: 0, newBundles: 0, bundles: [], }); @@ -67,18 +66,18 @@ export function assignBundlesToWorkers(bundles: Bundle[], maxWorkerCount: number /** * separate the bundles which do and don't have module - * counts and sort them by [moduleCount, id] + * counts and sort them by [workUnits, id] */ const bundlesWithCountsDesc = bundles - .filter((b) => b.cache.getModuleCount() !== undefined) + .filter((b) => b.cache.getWorkUnits() !== undefined) .sort( descending( - (b) => b.cache.getModuleCount(), + (b) => b.cache.getWorkUnits(), (b) => b.id ) ); const bundlesWithoutModuleCounts = bundles - .filter((b) => b.cache.getModuleCount() === undefined) + .filter((b) => b.cache.getWorkUnits() === undefined) .sort(descending((b) => b.id)); /** @@ -87,9 +86,9 @@ export function assignBundlesToWorkers(bundles: Bundle[], maxWorkerCount: number * with module counts are assigned */ while (bundlesWithCountsDesc.length) { - const [smallestWorker, nextSmallestWorker] = workers.sort(ascending((w) => w.moduleCount)); + const [smallestWorker, nextSmallestWorker] = workers.sort(ascending((w) => w.workUnits)); - while (!nextSmallestWorker || smallestWorker.moduleCount <= nextSmallestWorker.moduleCount) { + while (!nextSmallestWorker || smallestWorker.workUnits <= nextSmallestWorker.workUnits) { const bundle = bundlesWithCountsDesc.shift(); if (!bundle) { @@ -104,7 +103,7 @@ export function assignBundlesToWorkers(bundles: Bundle[], maxWorkerCount: number * assign bundles without module counts to workers round-robin * starting with the smallest workers */ - workers.sort(ascending((w) => w.moduleCount)); + workers.sort(ascending((w) => w.workUnits)); while (bundlesWithoutModuleCounts.length) { for (const worker of workers) { const bundle = bundlesWithoutModuleCounts.shift(); diff --git a/packages/kbn-optimizer/src/optimizer/filter_by_id.test.ts b/packages/kbn-optimizer/src/optimizer/filter_by_id.test.ts new file mode 100644 index 0000000000000..3e848fe616b49 --- /dev/null +++ b/packages/kbn-optimizer/src/optimizer/filter_by_id.test.ts @@ -0,0 +1,72 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { filterById, HasId } from './filter_by_id'; + +const bundles: HasId[] = [ + { id: 'foo' }, + { id: 'bar' }, + { id: 'abc' }, + { id: 'abcd' }, + { id: 'abcde' }, + { id: 'example_a' }, +]; + +const print = (result: HasId[]) => + result + .map((b) => b.id) + .sort((a, b) => a.localeCompare(b)) + .join(', '); + +it('[] matches everything', () => { + expect(print(filterById([], bundles))).toMatchInlineSnapshot( + `"abc, abcd, abcde, bar, example_a, foo"` + ); +}); + +it('* matches everything', () => { + expect(print(filterById(['*'], bundles))).toMatchInlineSnapshot( + `"abc, abcd, abcde, bar, example_a, foo"` + ); +}); + +it('combines mutliple filters to select any bundle which is matched', () => { + expect(print(filterById(['foo', 'bar'], bundles))).toMatchInlineSnapshot(`"bar, foo"`); + expect(print(filterById(['bar', 'abc*'], bundles))).toMatchInlineSnapshot( + `"abc, abcd, abcde, bar"` + ); +}); + +it('matches everything if any filter is *', () => { + expect(print(filterById(['*', '!abc*'], bundles))).toMatchInlineSnapshot( + `"abc, abcd, abcde, bar, example_a, foo"` + ); +}); + +it('only matches bundles which are matched by an entire single filter', () => { + expect(print(filterById(['*,!abc*'], bundles))).toMatchInlineSnapshot(`"bar, example_a, foo"`); +}); + +it('handles purely positive filters', () => { + expect(print(filterById(['abc*'], bundles))).toMatchInlineSnapshot(`"abc, abcd, abcde"`); +}); + +it('handles purely negative filters', () => { + expect(print(filterById(['!abc*'], bundles))).toMatchInlineSnapshot(`"bar, example_a, foo"`); +}); diff --git a/packages/kbn-optimizer/src/optimizer/filter_by_id.ts b/packages/kbn-optimizer/src/optimizer/filter_by_id.ts new file mode 100644 index 0000000000000..ccf61a9efc880 --- /dev/null +++ b/packages/kbn-optimizer/src/optimizer/filter_by_id.ts @@ -0,0 +1,48 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export interface HasId { + id: string; +} + +function parseFilter(filter: string) { + const positive: RegExp[] = []; + const negative: RegExp[] = []; + + for (const segment of filter.split(',')) { + let trimmed = segment.trim(); + let list = positive; + + if (trimmed.startsWith('!')) { + trimmed = trimmed.slice(1); + list = negative; + } + + list.push(new RegExp(`^${trimmed.split('*').join('.*')}$`)); + } + + return (bundle: HasId) => + (!positive.length || positive.some((p) => p.test(bundle.id))) && + (!negative.length || !negative.some((p) => p.test(bundle.id))); +} + +export function filterById(filterStrings: string[], bundles: T[]) { + const filters = filterStrings.map(parseFilter); + return bundles.filter((b) => !filters.length || filters.some((f) => f(b))); +} diff --git a/packages/kbn-optimizer/src/optimizer/get_plugin_bundles.test.ts b/packages/kbn-optimizer/src/optimizer/get_plugin_bundles.test.ts index bbd3ddc11f448..a70cfc759dd55 100644 --- a/packages/kbn-optimizer/src/optimizer/get_plugin_bundles.test.ts +++ b/packages/kbn-optimizer/src/optimizer/get_plugin_bundles.test.ts @@ -32,18 +32,21 @@ it('returns a bundle for core and each plugin', () => { id: 'foo', isUiPlugin: true, extraPublicDirs: [], + manifestPath: '/repo/plugins/foo/kibana.json', }, { directory: '/repo/plugins/bar', id: 'bar', isUiPlugin: false, extraPublicDirs: [], + manifestPath: '/repo/plugins/bar/kibana.json', }, { directory: '/outside/of/repo/plugins/baz', id: 'baz', isUiPlugin: true, extraPublicDirs: [], + manifestPath: '/outside/of/repo/plugins/baz/kibana.json', }, ], '/repo' @@ -53,6 +56,7 @@ it('returns a bundle for core and each plugin', () => { Object { "contextDir": /plugins/foo, "id": "foo", + "manifestPath": /plugins/foo/kibana.json, "outputDir": /plugins/foo/target/public, "publicDirNames": Array [ "public", @@ -63,6 +67,7 @@ it('returns a bundle for core and each plugin', () => { Object { "contextDir": "/outside/of/repo/plugins/baz", "id": "baz", + "manifestPath": "/outside/of/repo/plugins/baz/kibana.json", "outputDir": "/outside/of/repo/plugins/baz/target/public", "publicDirNames": Array [ "public", diff --git a/packages/kbn-optimizer/src/optimizer/get_plugin_bundles.ts b/packages/kbn-optimizer/src/optimizer/get_plugin_bundles.ts index 2635289088725..04ab992addeec 100644 --- a/packages/kbn-optimizer/src/optimizer/get_plugin_bundles.ts +++ b/packages/kbn-optimizer/src/optimizer/get_plugin_bundles.ts @@ -35,6 +35,7 @@ export function getPluginBundles(plugins: KibanaPlatformPlugin[], repoRoot: stri sourceRoot: repoRoot, contextDir: p.directory, outputDir: Path.resolve(p.directory, 'target/public'), + manifestPath: p.manifestPath, }) ); } diff --git a/packages/kbn-optimizer/src/optimizer/kibana_platform_plugins.test.ts b/packages/kbn-optimizer/src/optimizer/kibana_platform_plugins.test.ts index f7b457ca42c6d..06fffc953f58b 100644 --- a/packages/kbn-optimizer/src/optimizer/kibana_platform_plugins.test.ts +++ b/packages/kbn-optimizer/src/optimizer/kibana_platform_plugins.test.ts @@ -40,24 +40,28 @@ it('parses kibana.json files of plugins found in pluginDirs', () => { "extraPublicDirs": Array [], "id": "bar", "isUiPlugin": true, + "manifestPath": /packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/bar/kibana.json, }, Object { "directory": /packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/foo, "extraPublicDirs": Array [], "id": "foo", "isUiPlugin": true, + "manifestPath": /packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/foo/kibana.json, }, Object { "directory": /packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/nested/baz, "extraPublicDirs": Array [], "id": "baz", "isUiPlugin": false, + "manifestPath": /packages/kbn-optimizer/src/__fixtures__/mock_repo/plugins/nested/baz/kibana.json, }, Object { "directory": /packages/kbn-optimizer/src/__fixtures__/mock_repo/test_plugins/test_baz, "extraPublicDirs": Array [], "id": "test_baz", "isUiPlugin": false, + "manifestPath": /packages/kbn-optimizer/src/__fixtures__/mock_repo/test_plugins/test_baz/kibana.json, }, ] `); diff --git a/packages/kbn-optimizer/src/optimizer/kibana_platform_plugins.ts b/packages/kbn-optimizer/src/optimizer/kibana_platform_plugins.ts index 83637691004f4..b489c53be47b9 100644 --- a/packages/kbn-optimizer/src/optimizer/kibana_platform_plugins.ts +++ b/packages/kbn-optimizer/src/optimizer/kibana_platform_plugins.ts @@ -24,6 +24,7 @@ import loadJsonFile from 'load-json-file'; export interface KibanaPlatformPlugin { readonly directory: string; + readonly manifestPath: string; readonly id: string; readonly isUiPlugin: boolean; readonly extraPublicDirs: string[]; @@ -92,6 +93,7 @@ function readKibanaPlatformPlugin(manifestPath: string): KibanaPlatformPlugin { return { directory: Path.dirname(manifestPath), + manifestPath, id: manifest.id, isUiPlugin: !!manifest.ui, extraPublicDirs: extraPublicDirs || [], diff --git a/packages/kbn-optimizer/src/optimizer/optimizer_config.test.ts b/packages/kbn-optimizer/src/optimizer/optimizer_config.test.ts index 5b46d67479fd5..f97646e2bbbd3 100644 --- a/packages/kbn-optimizer/src/optimizer/optimizer_config.test.ts +++ b/packages/kbn-optimizer/src/optimizer/optimizer_config.test.ts @@ -21,6 +21,7 @@ jest.mock('./assign_bundles_to_workers.ts'); jest.mock('./kibana_platform_plugins.ts'); jest.mock('./get_plugin_bundles.ts'); jest.mock('../common/theme_tags.ts'); +jest.mock('./filter_by_id.ts'); import Path from 'path'; import Os from 'os'; @@ -113,6 +114,7 @@ describe('OptimizerConfig::parseOptions()', () => { Object { "cache": true, "dist": false, + "filters": Array [], "includeCoreBundle": false, "inspectWorkers": false, "maxWorkerCount": 2, @@ -139,6 +141,7 @@ describe('OptimizerConfig::parseOptions()', () => { Object { "cache": false, "dist": false, + "filters": Array [], "includeCoreBundle": false, "inspectWorkers": false, "maxWorkerCount": 2, @@ -165,6 +168,7 @@ describe('OptimizerConfig::parseOptions()', () => { Object { "cache": true, "dist": false, + "filters": Array [], "includeCoreBundle": false, "inspectWorkers": false, "maxWorkerCount": 2, @@ -193,6 +197,7 @@ describe('OptimizerConfig::parseOptions()', () => { Object { "cache": true, "dist": false, + "filters": Array [], "includeCoreBundle": false, "inspectWorkers": false, "maxWorkerCount": 2, @@ -218,6 +223,7 @@ describe('OptimizerConfig::parseOptions()', () => { Object { "cache": true, "dist": false, + "filters": Array [], "includeCoreBundle": false, "inspectWorkers": false, "maxWorkerCount": 2, @@ -243,6 +249,7 @@ describe('OptimizerConfig::parseOptions()', () => { Object { "cache": true, "dist": false, + "filters": Array [], "includeCoreBundle": false, "inspectWorkers": false, "maxWorkerCount": 100, @@ -265,6 +272,7 @@ describe('OptimizerConfig::parseOptions()', () => { Object { "cache": false, "dist": false, + "filters": Array [], "includeCoreBundle": false, "inspectWorkers": false, "maxWorkerCount": 100, @@ -287,6 +295,7 @@ describe('OptimizerConfig::parseOptions()', () => { Object { "cache": false, "dist": false, + "filters": Array [], "includeCoreBundle": false, "inspectWorkers": false, "maxWorkerCount": 100, @@ -310,6 +319,7 @@ describe('OptimizerConfig::parseOptions()', () => { Object { "cache": false, "dist": false, + "filters": Array [], "includeCoreBundle": false, "inspectWorkers": false, "maxWorkerCount": 100, @@ -333,6 +343,7 @@ describe('OptimizerConfig::parseOptions()', () => { Object { "cache": true, "dist": false, + "filters": Array [], "includeCoreBundle": false, "inspectWorkers": false, "maxWorkerCount": 100, @@ -358,6 +369,7 @@ describe('OptimizerConfig::create()', () => { const findKibanaPlatformPlugins: jest.Mock = jest.requireMock('./kibana_platform_plugins.ts') .findKibanaPlatformPlugins; const getPluginBundles: jest.Mock = jest.requireMock('./get_plugin_bundles.ts').getPluginBundles; + const filterById: jest.Mock = jest.requireMock('./filter_by_id.ts').filterById; beforeEach(() => { if ('mock' in OptimizerConfig.parseOptions) { @@ -370,6 +382,7 @@ describe('OptimizerConfig::create()', () => { ]); findKibanaPlatformPlugins.mockReturnValue(Symbol('new platform plugins')); getPluginBundles.mockReturnValue([Symbol('bundle1'), Symbol('bundle2')]); + filterById.mockReturnValue(Symbol('filtered bundles')); jest.spyOn(OptimizerConfig, 'parseOptions').mockImplementation((): any => ({ cache: Symbol('parsed cache'), @@ -382,6 +395,7 @@ describe('OptimizerConfig::create()', () => { themeTags: Symbol('theme tags'), inspectWorkers: Symbol('parsed inspect workers'), profileWebpack: Symbol('parsed profile webpack'), + filters: [], })); }); @@ -392,10 +406,7 @@ describe('OptimizerConfig::create()', () => { expect(config).toMatchInlineSnapshot(` OptimizerConfig { - "bundles": Array [ - Symbol(bundle1), - Symbol(bundle2), - ], + "bundles": Symbol(filtered bundles), "cache": Symbol(parsed cache), "dist": Symbol(parsed dist), "inspectWorkers": Symbol(parsed inspect workers), @@ -431,6 +442,32 @@ describe('OptimizerConfig::create()', () => { } `); + expect(filterById.mock).toMatchInlineSnapshot(` + Object { + "calls": Array [ + Array [ + Array [], + Array [ + Symbol(bundle1), + Symbol(bundle2), + ], + ], + ], + "instances": Array [ + [Window], + ], + "invocationCallOrder": Array [ + 23, + ], + "results": Array [ + Object { + "type": "return", + "value": Symbol(filtered bundles), + }, + ], + } + `); + expect(getPluginBundles.mock).toMatchInlineSnapshot(` Object { "calls": Array [ diff --git a/packages/kbn-optimizer/src/optimizer/optimizer_config.ts b/packages/kbn-optimizer/src/optimizer/optimizer_config.ts index 7757004139d0d..0e588ab36238b 100644 --- a/packages/kbn-optimizer/src/optimizer/optimizer_config.ts +++ b/packages/kbn-optimizer/src/optimizer/optimizer_config.ts @@ -31,6 +31,7 @@ import { import { findKibanaPlatformPlugins, KibanaPlatformPlugin } from './kibana_platform_plugins'; import { getPluginBundles } from './get_plugin_bundles'; +import { filterById } from './filter_by_id'; function pickMaxWorkerCount(dist: boolean) { // don't break if cpus() returns nothing, or an empty array @@ -77,6 +78,18 @@ interface Options { pluginScanDirs?: string[]; /** absolute paths that should be added to the default scan dirs */ extraPluginScanDirs?: string[]; + /** + * array of comma separated patterns that will be matched against bundle ids. + * bundles will only be built if they match one of the specified patterns. + * `*` can exist anywhere in each pattern and will match anything, `!` inverts the pattern + * + * examples: + * --filter foo --filter bar # [foo, bar], excludes [foobar] + * --filter foo,bar # [foo, bar], excludes [foobar] + * --filter foo* # [foo, foobar], excludes [bar] + * --filter f*r # [foobar], excludes [foo, bar] + */ + filter?: string[]; /** flag that causes the core bundle to be built along with plugins */ includeCoreBundle?: boolean; @@ -103,6 +116,7 @@ interface ParsedOptions { dist: boolean; pluginPaths: string[]; pluginScanDirs: string[]; + filters: string[]; inspectWorkers: boolean; includeCoreBundle: boolean; themeTags: ThemeTags; @@ -118,6 +132,7 @@ export class OptimizerConfig { const inspectWorkers = !!options.inspectWorkers; const cache = options.cache !== false && !process.env.KBN_OPTIMIZER_NO_CACHE; const includeCoreBundle = !!options.includeCoreBundle; + const filters = options.filter || []; const repoRoot = options.repoRoot; if (!Path.isAbsolute(repoRoot)) { @@ -172,6 +187,7 @@ export class OptimizerConfig { cache, pluginScanDirs, pluginPaths, + filters, inspectWorkers, includeCoreBundle, themeTags, @@ -198,7 +214,7 @@ export class OptimizerConfig { ]; return new OptimizerConfig( - bundles, + filterById(options.filters, bundles), options.cache, options.watch, options.inspectWorkers, diff --git a/packages/kbn-optimizer/src/worker/bundle_ref_module.ts b/packages/kbn-optimizer/src/worker/bundle_ref_module.ts index cde25564cf528..563b4ecb4bc37 100644 --- a/packages/kbn-optimizer/src/worker/bundle_ref_module.ts +++ b/packages/kbn-optimizer/src/worker/bundle_ref_module.ts @@ -10,6 +10,7 @@ // @ts-ignore not typed by @types/webpack import Module from 'webpack/lib/Module'; +import { BundleRef } from '../common'; export class BundleRefModule extends Module { public built = false; @@ -17,12 +18,12 @@ export class BundleRefModule extends Module { public buildInfo?: any; public exportsArgument = '__webpack_exports__'; - constructor(public readonly exportId: string) { + constructor(public readonly ref: BundleRef) { super('kbn/bundleRef', null); } libIdent() { - return this.exportId; + return this.ref.exportId; } chunkCondition(chunk: any) { @@ -30,7 +31,7 @@ export class BundleRefModule extends Module { } identifier() { - return '@kbn/bundleRef ' + JSON.stringify(this.exportId); + return '@kbn/bundleRef ' + JSON.stringify(this.ref.exportId); } readableIdentifier() { @@ -51,7 +52,7 @@ export class BundleRefModule extends Module { source() { return ` __webpack_require__.r(__webpack_exports__); - var ns = __kbnBundles__.get('${this.exportId}'); + var ns = __kbnBundles__.get('${this.ref.exportId}'); Object.defineProperties(__webpack_exports__, Object.getOwnPropertyDescriptors(ns)) `; } diff --git a/packages/kbn-optimizer/src/worker/bundle_refs_plugin.ts b/packages/kbn-optimizer/src/worker/bundle_refs_plugin.ts index 9c4d5ed7f8a98..5396d11726f7a 100644 --- a/packages/kbn-optimizer/src/worker/bundle_refs_plugin.ts +++ b/packages/kbn-optimizer/src/worker/bundle_refs_plugin.ts @@ -44,6 +44,7 @@ export class BundleRefsPlugin { private readonly resolvedRefEntryCache = new Map>(); private readonly resolvedRequestCache = new Map>(); private readonly ignorePrefix = Path.resolve(this.bundle.contextDir) + Path.sep; + private allowedBundleIds = new Set(); constructor(private readonly bundle: Bundle, private readonly bundleRefs: BundleRefs) {} @@ -81,6 +82,45 @@ export class BundleRefsPlugin { } ); }); + + compiler.hooks.compilation.tap('BundleRefsPlugin/getRequiredBundles', (compilation) => { + this.allowedBundleIds.clear(); + + const manifestPath = this.bundle.manifestPath; + if (!manifestPath) { + return; + } + + const deps = this.bundle.readBundleDeps(); + for (const ref of this.bundleRefs.forBundleIds([...deps.explicit, ...deps.implicit])) { + this.allowedBundleIds.add(ref.bundleId); + } + + compilation.hooks.additionalAssets.tap('BundleRefsPlugin/watchManifest', () => { + compilation.fileDependencies.add(manifestPath); + }); + + compilation.hooks.finishModules.tapPromise( + 'BundleRefsPlugin/finishModules', + async (modules) => { + const usedBundleIds = (modules as any[]) + .filter((m: any): m is BundleRefModule => m instanceof BundleRefModule) + .map((m) => m.ref.bundleId); + + const unusedBundleIds = deps.explicit + .filter((id) => !usedBundleIds.includes(id)) + .join(', '); + + if (unusedBundleIds) { + const error = new Error( + `Bundle for [${this.bundle.id}] lists [${unusedBundleIds}] as a required bundle, but does not use it. Please remove it.` + ); + (error as any).file = manifestPath; + compilation.errors.push(error); + } + } + ); + }); } private cachedResolveRefEntry(ref: BundleRef) { @@ -170,21 +210,29 @@ export class BundleRefsPlugin { return; } - const eligibleRefs = this.bundleRefs.filterByContextPrefix(this.bundle, resolved); - if (!eligibleRefs.length) { + const possibleRefs = this.bundleRefs.filterByContextPrefix(this.bundle, resolved); + if (!possibleRefs.length) { // import doesn't match a bundle context return; } - for (const ref of eligibleRefs) { + for (const ref of possibleRefs) { const resolvedEntry = await this.cachedResolveRefEntry(ref); - if (resolved === resolvedEntry) { - return new BundleRefModule(ref.exportId); + if (resolved !== resolvedEntry) { + continue; } + + if (!this.allowedBundleIds.has(ref.bundleId)) { + throw new Error( + `import [${request}] references a public export of the [${ref.bundleId}] bundle, but that bundle is not in the "requiredPlugins" or "requiredBundles" list in the plugin manifest [${this.bundle.manifestPath}]` + ); + } + + return new BundleRefModule(ref); } - const bundleId = Array.from(new Set(eligibleRefs.map((r) => r.bundleId))).join(', '); - const publicDir = eligibleRefs.map((r) => r.entry).join(', '); + const bundleId = Array.from(new Set(possibleRefs.map((r) => r.bundleId))).join(', '); + const publicDir = possibleRefs.map((r) => r.entry).join(', '); throw new Error( `import [${request}] references a non-public export of the [${bundleId}] bundle and must point to one of the public directories: [${publicDir}]` ); diff --git a/packages/kbn-optimizer/src/worker/run_compilers.ts b/packages/kbn-optimizer/src/worker/run_compilers.ts index ca7673748bde9..c7be943d65a48 100644 --- a/packages/kbn-optimizer/src/worker/run_compilers.ts +++ b/packages/kbn-optimizer/src/worker/run_compilers.ts @@ -50,6 +50,15 @@ import { const PLUGIN_NAME = '@kbn/optimizer'; +/** + * sass-loader creates about a 40% overhead on the overall optimizer runtime, and + * so this constant is used to indicate to assignBundlesToWorkers() that there is + * extra work done in a bundle that has a lot of scss imports. The value is + * arbitrary and just intended to weigh the bundles so that they are distributed + * across mulitple workers on machines with lots of cores. + */ +const EXTRA_SCSS_WORK_UNITS = 100; + /** * Create an Observable for a specific child compiler + bundle */ @@ -102,6 +111,11 @@ const observeCompiler = ( const bundleRefExportIds: string[] = []; const referencedFiles = new Set(); let normalModuleCount = 0; + let workUnits = stats.compilation.fileDependencies.size; + + if (bundle.manifestPath) { + referencedFiles.add(bundle.manifestPath); + } for (const module of stats.compilation.modules) { if (isNormalModule(module)) { @@ -111,6 +125,15 @@ const observeCompiler = ( if (!parsedPath.dirs.includes('node_modules')) { referencedFiles.add(path); + + if (path.endsWith('.scss')) { + workUnits += EXTRA_SCSS_WORK_UNITS; + + for (const depPath of module.buildInfo.fileDependencies) { + referencedFiles.add(depPath); + } + } + continue; } @@ -127,7 +150,7 @@ const observeCompiler = ( } if (module instanceof BundleRefModule) { - bundleRefExportIds.push(module.exportId); + bundleRefExportIds.push(module.ref.exportId); continue; } @@ -158,6 +181,7 @@ const observeCompiler = ( optimizerCacheKey: workerConfig.optimizerCacheKey, cacheKey: bundle.createCacheKey(files, mtimes), moduleCount: normalModuleCount, + workUnits, files, }); diff --git a/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts b/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts index 6cbdc5ec7fc20..e1d3bf1a8d901 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts @@ -148,7 +148,7 @@ export const schema = Joi.object() browser: Joi.object() .keys({ - type: Joi.string().valid('chrome', 'firefox', 'ie', 'msedge').default('chrome'), + type: Joi.string().valid('chrome', 'firefox', 'msedge').default('chrome'), logPollingMs: Joi.number().default(100), acceptInsecureCerts: Joi.boolean().default(false), diff --git a/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/reporter.js b/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/reporter.js index 90bea1c3aa293..f4200d6f47574 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/reporter.js +++ b/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/reporter.js @@ -36,6 +36,8 @@ export function MochaReporterProvider({ getService }) { let originalLogWriters; let reporterCaptureStartTime; + const failuresOverTime = []; + return class MochaReporter extends Mocha.reporters.Base { constructor(runner, options) { super(runner, options); @@ -154,30 +156,50 @@ export function MochaReporterProvider({ getService }) { // - I started by trying to extract the Base.list() logic from mocha // but it's a lot more complicated than this is horrible. // - In order to fix the numbering and indentation we monkey-patch - // console.log and parse the logged output. + // Mocha.reporters.Base.consoleLog and parse the logged output. // let output = ''; - const realLog = console.log; - console.log = (...args) => (output += `${format(...args)}\n`); + const realLog = Mocha.reporters.Base.consoleLog; + Mocha.reporters.Base.consoleLog = (...args) => (output += `${format(...args)}\n`); try { Mocha.reporters.Base.list([runnable]); } finally { - console.log = realLog; + Mocha.reporters.Base.consoleLog = realLog; } + const outputLines = output.split('\n'); + + const errorMarkerStart = outputLines.reduce((index, line, i) => { + if (index >= 0) { + return index; + } + return /Error:/.test(line) ? i : index; + }, -1); + + const errorMessage = outputLines + // drop the first ${errorMarkerStart} lines, (empty + test title) + .slice(errorMarkerStart) + // move leading colors behind leading spaces + .map((line) => line.replace(/^((?:\[.+m)+)(\s+)/, '$2$1')) + .map((line) => ` ${line}`) + .join('\n'); + log.write( - `- ${colors.fail(`${symbols.err} fail: "${runnable.fullTitle()}"`)}` + - '\n' + - output - .split('\n') - // drop the first two lines, (empty + test title) - .slice(2) - // move leading colors behind leading spaces - .map((line) => line.replace(/^((?:\[.+m)+)(\s+)/, '$2$1')) - .map((line) => ` ${line}`) - .join('\n') + `- ${colors.fail(`${symbols.err} fail: ${runnable.fullTitle()}`)}` + '\n' + errorMessage ); + // Prefer to reuse the nice Mocha nested title format for final summary + const nestedTitleFormat = outputLines + .slice(1, errorMarkerStart) + .join('\n') + // make sure to remove the list number + .replace(/\d+\)/, ''); + + failuresOverTime.push({ + title: nestedTitleFormat, + error: errorMessage, + }); + // failed hooks trigger the `onFail(runnable)` callback, so we snapshot the logs for // them here. Tests will re-capture the snapshot in `onTestEnd()` snapshotLogsForRunnable(runnable); @@ -188,7 +210,7 @@ export function MochaReporterProvider({ getService }) { log.setWriters(originalLogWriters); } - writeEpilogue(log, this.stats); + writeEpilogue(log, this.stats, failuresOverTime); }; }; } diff --git a/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/write_epilogue.js b/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/write_epilogue.js index 72a011ce510bc..0ee429067254b 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/write_epilogue.js +++ b/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/write_epilogue.js @@ -20,7 +20,7 @@ import * as colors from './colors'; import { ms } from './ms'; -export function writeEpilogue(log, stats) { +export function writeEpilogue(log, stats, failuresDetail) { // header log.write(''); @@ -35,6 +35,12 @@ export function writeEpilogue(log, stats) { // failures if (stats.failures) { log.write('%d failing', stats.failures); + log.write(''); + failuresDetail.forEach(({ title, error }, i) => { + log.write('%d) %s', i + 1, title); + log.write(''); + log.write('%s', error); + }); } // footer diff --git a/packages/kbn-ui-shared-deps/package.json b/packages/kbn-ui-shared-deps/package.json index 6ea4a621f92f6..8398d1c081da6 100644 --- a/packages/kbn-ui-shared-deps/package.json +++ b/packages/kbn-ui-shared-deps/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@elastic/charts": "19.8.1", - "@elastic/eui": "24.1.0", + "@elastic/eui": "26.3.1", "@elastic/numeral": "^2.5.0", "@kbn/i18n": "1.0.0", "@kbn/monaco": "1.0.0", diff --git a/src/cli/cluster/cluster_manager.ts b/src/cli/cluster/cluster_manager.ts index 6db6199b391e1..f193f33e6f47e 100644 --- a/src/cli/cluster/cluster_manager.ts +++ b/src/cli/cluster/cluster_manager.ts @@ -261,7 +261,7 @@ export class ClusterManager { /debug\.log$/, ...pluginInternalDirsIgnore, fromRoot('src/legacy/server/sass/__tmp__'), - fromRoot('x-pack/plugins/reporting/.chromium'), + fromRoot('x-pack/plugins/reporting/chromium'), fromRoot('x-pack/plugins/security_solution/cypress'), fromRoot('x-pack/plugins/apm/e2e'), fromRoot('x-pack/plugins/apm/scripts'), diff --git a/src/core/public/application/scoped_history.mock.ts b/src/core/public/application/scoped_history.mock.ts index 56de97e630bf0..41c72306a99f9 100644 --- a/src/core/public/application/scoped_history.mock.ts +++ b/src/core/public/application/scoped_history.mock.ts @@ -27,7 +27,8 @@ const createMock = ({ hash = '', key, state, -}: Partial = {}) => { + ...overrides +}: Partial = {}) => { const mock: ScopedHistoryMock = { block: jest.fn(), createHref: jest.fn(), @@ -38,6 +39,7 @@ const createMock = ({ listen: jest.fn(), push: jest.fn(), replace: jest.fn(), + ...overrides, action: 'PUSH', length: 1, location: { diff --git a/src/core/public/chrome/chrome_service.tsx b/src/core/public/chrome/chrome_service.tsx index 1b894bc400f08..d29120e6ee9ac 100644 --- a/src/core/public/chrome/chrome_service.tsx +++ b/src/core/public/chrome/chrome_service.tsx @@ -17,7 +17,7 @@ * under the License. */ -import { Breadcrumb as EuiBreadcrumb, IconType } from '@elastic/eui'; +import { EuiBreadcrumb, IconType } from '@elastic/eui'; import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { BehaviorSubject, combineLatest, merge, Observable, of, ReplaySubject } from 'rxjs'; 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 9fee7b50f371b..9ecbc055e3320 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 @@ -149,7 +149,7 @@ exports[`CollapsibleNav renders links grouped by category 1`] = ` "euiIconType": "logoSecurity", "id": "security", "label": "Security", - "order": 3000, + "order": 4000, }, "data-test-subj": "siem", "href": "siem", @@ -164,7 +164,7 @@ exports[`CollapsibleNav renders links grouped by category 1`] = ` "euiIconType": "logoObservability", "id": "observability", "label": "Observability", - "order": 2000, + "order": 3000, }, "data-test-subj": "metrics", "href": "metrics", @@ -233,7 +233,7 @@ exports[`CollapsibleNav renders links grouped by category 1`] = ` "euiIconType": "logoObservability", "id": "observability", "label": "Observability", - "order": 2000, + "order": 3000, }, "data-test-subj": "logs", "href": "logs", @@ -372,12 +372,13 @@ exports[`CollapsibleNav renders links grouped by category 1`] = ` handler={[Function]} /> } /> @@ -3908,16 +3909,9 @@ exports[`CollapsibleNav renders the default nav 2`] = ` handler={[Function]} /> - - } - /> - + />