diff --git a/.eslintrc.js b/.eslintrc.js index 6daccfd9f4363..e94752bc0c093 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -69,12 +69,6 @@ module.exports = { 'jsx-a11y/no-onchange': 'off', }, }, - { - files: ['src/legacy/core_plugins/data/**/*.{js,ts,tsx}'], - rules: { - 'react-hooks/exhaustive-deps': 'off', - }, - }, { files: ['src/legacy/core_plugins/expressions/**/*.{js,ts,tsx}'], rules: { diff --git a/.i18nrc.json b/.i18nrc.json index 07878ed3c15fb..78c4be6f4a356 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -3,11 +3,9 @@ "common.ui": "src/legacy/ui", "console": "src/plugins/console", "core": "src/core", + "discover": "src/plugins/discover", "dashboard": "src/plugins/dashboard", - "data": [ - "src/legacy/core_plugins/data", - "src/plugins/data" - ], + "data": "src/plugins/data", "embeddableApi": "src/plugins/embeddable", "embeddableExamples": "examples/embeddable_examples", "share": "src/plugins/share", @@ -38,8 +36,8 @@ "server": "src/legacy/server", "statusPage": "src/legacy/core_plugins/status_page", "telemetry": [ - "src/legacy/core_plugins/telemetry", - "src/plugins/telemetry" + "src/plugins/telemetry", + "src/plugins/telemetry_management_section" ], "tileMap": "src/legacy/core_plugins/tile_map", "timelion": ["src/legacy/core_plugins/timelion", "src/legacy/core_plugins/vis_type_timelion", "src/plugins/timelion"], diff --git a/Jenkinsfile b/Jenkinsfile index d43da6e0bee04..79d3c93006cb6 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -40,7 +40,12 @@ kibanaPipeline(timeoutMinutes: 135, checkPrChanges: true) { 'xpack-ciGroup9': kibanaPipeline.xpackCiGroupProcess(9), 'xpack-ciGroup10': kibanaPipeline.xpackCiGroupProcess(10), 'xpack-accessibility': kibanaPipeline.functionalTestProcess('xpack-accessibility', './test/scripts/jenkins_xpack_accessibility.sh'), - 'xpack-siemCypress': kibanaPipeline.functionalTestProcess('xpack-siemCypress', './test/scripts/jenkins_siem_cypress.sh'), + 'xpack-siemCypress': { processNumber -> + whenChanged(['x-pack/legacy/plugins/siem/', 'x-pack/test/siem_cypress/']) { + kibanaPipeline.functionalTestProcess('xpack-siemCypress', './test/scripts/jenkins_siem_cypress.sh')(processNumber) + } + }, + // 'xpack-visualRegression': kibanaPipeline.functionalTestProcess('xpack-visualRegression', './test/scripts/jenkins_xpack_visual_regression.sh'), ]), ]) diff --git a/docs/api/saved-objects/bulk_create.asciidoc b/docs/api/saved-objects/bulk_create.asciidoc index ca8cc0f287015..d649684bc30f2 100644 --- a/docs/api/saved-objects/bulk_create.asciidoc +++ b/docs/api/saved-objects/bulk_create.asciidoc @@ -11,6 +11,15 @@ experimental[] Create multiple {kib} saved objects. `POST /api/saved_objects/_bulk_create` +`POST /s//api/saved_objects/_bulk_create` + + +[[saved-objects-api-bulk-create-path-params]] +==== Path parameters + +`space_id`:: + (Optional, string) An identifier for the space. If `space_id` is not provided in the URL the default space is used. + [[saved-objects-api-bulk-create-query-params]] ==== Query parameters @@ -38,7 +47,7 @@ experimental[] Create multiple {kib} saved objects. [[saved-objects-api-bulk-create-response-body]] ==== Response body -`saved_objects`:: +`saved_objects`:: (array) Top-level property the contains objects that represent the response for each of the requested objects. The order of the objects in the response is identical to the order of the objects in the request. Saved objects that are unable to persist are replaced with an error object. @@ -46,13 +55,13 @@ Saved objects that are unable to persist are replaced with an error object. [[saved-objects-api-bulk-create-codes]] ==== Response code -`200`:: +`200`:: Indicates a successful call. [[saved-objects-api-bulk-create-example]] ==== Example -Create an index pattern with the `my-pattern` ID, and a dashboard with the `my-dashboard` ID: +Create an index pattern with the `my-pattern` ID, and a dashboard with the `my-dashboard` ID: [source,js] -------------------------------------------------- @@ -67,7 +76,7 @@ POST api/saved_objects/_bulk_create }, { "type": "dashboard", - "id": "my-dashboard", + "id": "be3733a0-9efe-11e7-acb3-3dab96693fab", "attributes": { "title": "Look at my dashboard" } @@ -91,7 +100,7 @@ The API returns the following: } }, { - "id": "my-dashboard", + "id": "be3733a0-9efe-11e7-acb3-3dab96693fab", "type": "dashboard", "error": { "statusCode": 409, diff --git a/docs/api/saved-objects/bulk_get.asciidoc b/docs/api/saved-objects/bulk_get.asciidoc index 4f2cbcb980f82..3ef5823716d79 100644 --- a/docs/api/saved-objects/bulk_get.asciidoc +++ b/docs/api/saved-objects/bulk_get.asciidoc @@ -11,6 +11,14 @@ experimental[] Retrieve multiple {kib} saved objects by ID. `POST /api/saved_objects/_bulk_get` +`POST /s//api/saved_objects/_bulk_get` + +[[saved-objects-api-bulk-get-path-params]] +==== Path parameters + +`space_id`:: + (Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used. + [[saved-objects-api-bulk-get-request-body]] ==== Request Body @@ -18,15 +26,15 @@ experimental[] Retrieve multiple {kib} saved objects by ID. (Required, string) Valid options include `visualization`, `dashboard`, `search`, `index-pattern`, `config`, and `timelion-sheet`. `id`:: - (Required, string) ID of the retrieved object. + (Required, string) ID of the retrieved object. The ID includes the {kib} unique identifier or a custom identifier. `fields`:: (Optional, array) The fields returned in the object response. - + [[saved-objects-api-bulk-get-response-body]] ==== Response body -`saved_objects`:: +`saved_objects`:: (array) Top-level property the contains objects that represent the response for each of the requested objects. The order of the objects in the response is identical to the order of the objects in the request. Saved objects that are unable to persist are replaced with an error object. @@ -34,13 +42,13 @@ Saved objects that are unable to persist are replaced with an error object. [[saved-objects-api-bulk-get-body-codes]] ==== Response code -`200`:: - Indicates a successfully call. +`200`:: + Indicates a successful call. [[saved-objects-api-bulk-get-body-example]] ==== Example -Retrieve an index pattern with the `my-pattern` ID, and a dashboard with the `my-dashboard` ID: +Retrieve an index pattern with the `my-pattern` ID, and a dashboard with the `my-dashboard` ID: [source,js] -------------------------------------------------- @@ -52,7 +60,7 @@ POST api/saved_objects/_bulk_get }, { "type": "dashboard", - "id": "my-dashboard" + "id": "be3733a0-9efe-11e7-acb3-3dab96693fab" } ] -------------------------------------------------- diff --git a/docs/api/saved-objects/create.asciidoc b/docs/api/saved-objects/create.asciidoc index fecc3f3732f2a..634c71bb4eefe 100644 --- a/docs/api/saved-objects/create.asciidoc +++ b/docs/api/saved-objects/create.asciidoc @@ -13,9 +13,14 @@ experimental[] Create {kib} saved objects. `POST /api/saved_objects//` +`POST /s//saved_objects/` + [[saved-objects-api-create-path-params]] ==== Path parameters +`space_id`:: + (Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used. + ``:: (Required, string) Valid options include `visualization`, `dashboard`, `search`, `index-pattern`, `config`, and `timelion-sheet`. @@ -44,9 +49,9 @@ any data that you send to the API is properly formed. [[saved-objects-api-create-request-codes]] ==== Response code -`200`:: +`200`:: Indicates a successful call. - + [[saved-objects-api-create-example]] ==== Example diff --git a/docs/api/saved-objects/delete.asciidoc b/docs/api/saved-objects/delete.asciidoc index 4a96cf554f784..c34f9b67dfd22 100644 --- a/docs/api/saved-objects/delete.asciidoc +++ b/docs/api/saved-objects/delete.asciidoc @@ -13,9 +13,14 @@ WARNING: Once you delete a saved object, _it cannot be recovered_. `DELETE /api/saved_objects//` +`DELETE /s//api/saved_objects//` + [[saved-objects-api-delete-path-params]] ==== Path parameters +`space_id`:: + (Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used. + `type`:: (Required, string) Valid options include `visualization`, `dashboard`, `search`, `index-pattern`, `config`, and `timelion-sheet`. @@ -25,7 +30,7 @@ WARNING: Once you delete a saved object, _it cannot be recovered_. [[saved-objects-api-delete-response-codes]] ==== Response code -`200`:: +`200`:: Indicates a successful call. ==== Examples diff --git a/docs/api/saved-objects/export.asciidoc b/docs/api/saved-objects/export.asciidoc index ee56e6bad75c8..1b4f50dda2ddb 100644 --- a/docs/api/saved-objects/export.asciidoc +++ b/docs/api/saved-objects/export.asciidoc @@ -11,15 +11,23 @@ experimental[] Retrieve sets of saved objects that you want to import into {kib} `POST /api/saved_objects/_export` +`POST /s//api/saved_objects/_export` + +[[saved-objects-api-export-path-params]] +==== Path parameters + +`space_id`:: + (Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used. + [[saved-objects-api-export-request-request-body]] ==== Request body `type`:: (Optional, array|string) The saved object types to include in the export. - + `objects`:: (Optional, array) A list of objects to export. - + `includeReferencesDeep`:: (Optional, boolean) Includes all of the referenced objects in the exported objects. @@ -50,7 +58,7 @@ When `excludeExportDetails=false` (the default) we append an export result detai [[export-objects-api-create-request-codes]] ==== Response code -`200`:: +`200`:: Indicates a successful call. [[ssaved-objects-api-create-example]] diff --git a/docs/api/saved-objects/find.asciidoc b/docs/api/saved-objects/find.asciidoc index f20ded78e0743..955c50922fde7 100644 --- a/docs/api/saved-objects/find.asciidoc +++ b/docs/api/saved-objects/find.asciidoc @@ -11,33 +11,41 @@ experimental[] Retrieve a paginated set of {kib} saved objects by various condit `GET /api/saved_objects/_find` +`GET /s//api/saved_objects/_find` + +[[saved-objects-api-find-path-params]] +==== Path parameters + +`space_id`:: + (Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used. + [[saved-objects-api-find-query-params]] ==== Query Parameters `type`:: (Required, array|string) The saved object types to include in the export. - + `per_page`:: (Optional, number) The number of objects to return per page. - + `page`:: (Optional, number) The page of objects to return. - + `search`:: (Optional, string) An Elasticsearch {ref}/query-dsl-simple-query-string-query.html[simple_query_string] query that filters the objects in the response. - + `default_search_operator`:: (Optional, string) The default operator to use for the `simple_query_string`. - + `search_fields`:: (Optional, array|string) The fields to perform the `simple_query_string` parsed query against. - + `fields`:: (Optional, array|string) The fields to return in the response. - + `sort_field`:: (Optional, string) The field that sorts the response. - + `has_reference`:: (Optional, object) Filters to objects that have a relationship with the type and ID combination. @@ -52,7 +60,7 @@ change. Use the find API for traditional paginated results, but avoid using it t [[saved-objects-api-find-request-codes]] ==== Response code -`200`:: +`200`:: Indicates a successful call. ==== Examples @@ -92,4 +100,3 @@ query parameter for each value: GET api/saved_objects/_find?fields=id&fields=title -------------------------------------------------- // KIBANA - diff --git a/docs/api/saved-objects/get.asciidoc b/docs/api/saved-objects/get.asciidoc index f0c22ced4b121..29f8ef67e0a83 100644 --- a/docs/api/saved-objects/get.asciidoc +++ b/docs/api/saved-objects/get.asciidoc @@ -11,9 +11,15 @@ experimental[] Retrieve a single {kib} saved object by ID. `GET /api/saved_objects//` +`GET /s//api/saved_objects//` + [[saved-objects-api-get-params]] ==== Path parameters +`space_id`:: + (Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used. + + `type`:: (Required, string) Valid options include `visualization`, `dashboard`, `search`, `index-pattern`, `config`, and `timelion-sheet`. @@ -23,10 +29,10 @@ experimental[] Retrieve a single {kib} saved object by ID. [[saved-objects-api-get-codes]] ==== Response code -`200`:: +`200`:: Indicates a successful call. -[[saved-objects-api-get-example]] +[[saved-objects-api-get-example]] ==== Example Retrieve the index pattern object with the `my-pattern` ID: @@ -50,3 +56,59 @@ The API returns the following: } } -------------------------------------------------- + +The following example retrieves a dashboard object in the `testspace` by id. + +[source,js] +-------------------------------------------------- +GET /s/testspace/api/saved_objects/dashboard/7adfa750-4c81-11e8-b3d7-01146121b73d +-------------------------------------------------- +// KIBANA + +The API returns the following: + +[source,js] +-------------------------------------------------- +{ + "id": "7adfa750-4c81-11e8-b3d7-01146121b73d", + "type": "dashboard", + "updated_at": "2019-07-23T00:11:07.059Z", + "version": "WzQ0LDFd", + "attributes": { + "title": "[Flights] Global Flight Dashboard", + "hits": 0, + "description": "Analyze mock flight data for ES-Air, Logstash Airways, Kibana Airlines and JetBeats", + "panelsJSON": "[{\"panelIndex\":\"1\",\"gridData\":{\"x\":0,\"y\":0,\"w\":32,\"h\":7,\"i\":\"1\"},\"embeddableConfig\":{},\"version\":\"6.3.0\",\"panelRefName\":\"panel_0\"},{\"panelIndex\":\"3\",\"gridData\":{\"x\":17,\"y\":7,\"w\":23,\"h\":12,\"i\":\"3\"},\"embeddableConfig\":{\"vis\":{\"colors\":{\"Average Ticket Price\":\"#0A50A1\",\"Flight Count\":\"#82B5D8\"},\"legendOpen\":false}},\"version\":\"6.3.0\",\"panelRefName\":\"panel_1\"},{\"panelIndex\":\"4\",\"gridData\":{\"x\":0,\"y\":85,\"w\":48,\"h\":15,\"i\":\"4\"},\"embeddableConfig\":{},\"version\":\"6.3.0\",\"panelRefName\":\"panel_2\"},{\"panelIndex\":\"5\",\"gridData\":{\"x\":0,\"y\":7,\"w\":17,\"h\":12,\"i\":\"5\"},\"embeddableConfig\":{\"vis\":{\"colors\":{\"ES-Air\":\"#447EBC\",\"JetBeats\":\"#65C5DB\",\"Kibana Airlines\":\"#BA43A9\",\"Logstash Airways\":\"#E5AC0E\"},\"legendOpen\":false}},\"version\":\"6.3.0\",\"panelRefName\":\"panel_3\"},{\"panelIndex\":\"6\",\"gridData\":{\"x\":24,\"y\":33,\"w\":24,\"h\":14,\"i\":\"6\"},\"embeddableConfig\":{\"vis\":{\"colors\":{\"Carrier Delay\":\"#5195CE\",\"Late Aircraft Delay\":\"#1F78C1\",\"NAS Delay\":\"#70DBED\",\"No Delay\":\"#BADFF4\",\"Security Delay\":\"#052B51\",\"Weather Delay\":\"#6ED0E0\"}}},\"version\":\"6.3.0\",\"panelRefName\":\"panel_4\"},{\"panelIndex\":\"7\",\"gridData\":{\"x\":24,\"y\":19,\"w\":24,\"h\":14,\"i\":\"7\"},\"embeddableConfig\":{},\"version\":\"6.3.0\",\"panelRefName\":\"panel_5\"},{\"panelIndex\":\"10\",\"gridData\":{\"x\":0,\"y\":35,\"w\":24,\"h\":12,\"i\":\"10\"},\"embeddableConfig\":{\"vis\":{\"colors\":{\"Count\":\"#1F78C1\"},\"legendOpen\":false}},\"version\":\"6.3.0\",\"panelRefName\":\"panel_6\"},{\"panelIndex\":\"13\",\"gridData\":{\"x\":10,\"y\":19,\"w\":14,\"h\":8,\"i\":\"13\"},\"embeddableConfig\":{\"vis\":{\"colors\":{\"Count\":\"#1F78C1\"},\"legendOpen\":false}},\"version\":\"6.3.0\",\"panelRefName\":\"panel_7\"},{\"panelIndex\":\"14\",\"gridData\":{\"x\":10,\"y\":27,\"w\":14,\"h\":8,\"i\":\"14\"},\"embeddableConfig\":{\"vis\":{\"colors\":{\"Count\":\"#1F78C1\"},\"legendOpen\":false}},\"version\":\"6.3.0\",\"panelRefName\":\"panel_8\"},{\"panelIndex\":\"18\",\"gridData\":{\"x\":24,\"y\":70,\"w\":24,\"h\":15,\"i\":\"18\"},\"embeddableConfig\":{\"mapCenter\":[27.421687059550266,15.371002131141724],\"mapZoom\":1},\"version\":\"6.3.0\",\"panelRefName\":\"panel_9\"},{\"panelIndex\":\"21\",\"gridData\":{\"x\":0,\"y\":62,\"w\":48,\"h\":8,\"i\":\"21\"},\"embeddableConfig\":{},\"version\":\"6.3.0\",\"panelRefName\":\"panel_10\"},{\"panelIndex\":\"22\",\"gridData\":{\"x\":32,\"y\":0,\"w\":16,\"h\":7,\"i\":\"22\"},\"embeddableConfig\":{},\"version\":\"6.3.0\",\"panelRefName\":\"panel_11\"},{\"panelIndex\":\"23\",\"gridData\":{\"x\":0,\"y\":70,\"w\":24,\"h\":15,\"i\":\"23\"},\"embeddableConfig\":{\"mapCenter\":[42.19556096274418,9.536742995308601e-7],\"mapZoom\":1},\"version\":\"6.3.0\",\"panelRefName\":\"panel_12\"},{\"panelIndex\":\"25\",\"gridData\":{\"x\":0,\"y\":19,\"w\":10,\"h\":8,\"i\":\"25\"},\"embeddableConfig\":{\"vis\":{\"defaultColors\":{\"0 - 50\":\"rgb(247,251,255)\",\"100 - 150\":\"rgb(107,174,214)\",\"150 - 200\":\"rgb(33,113,181)\",\"200 - 250\":\"rgb(8,48,107)\",\"50 - 100\":\"rgb(198,219,239)\"},\"legendOpen\":false}},\"version\":\"6.3.0\",\"panelRefName\":\"panel_13\"},{\"panelIndex\":\"27\",\"gridData\":{\"x\":0,\"y\":27,\"w\":10,\"h\":8,\"i\":\"27\"},\"embeddableConfig\":{\"vis\":{\"defaultColors\":{\"0 - 50\":\"rgb(247,251,255)\",\"100 - 150\":\"rgb(107,174,214)\",\"150 - 200\":\"rgb(33,113,181)\",\"200 - 250\":\"rgb(8,48,107)\",\"50 - 100\":\"rgb(198,219,239)\"},\"legendOpen\":false}},\"version\":\"6.3.0\",\"panelRefName\":\"panel_14\"},{\"panelIndex\":\"28\",\"gridData\":{\"x\":0,\"y\":47,\"w\":24,\"h\":15,\"i\":\"28\"},\"embeddableConfig\":{\"vis\":{\"defaultColors\":{\"0 -* Connection #0 to host 69c72adb58fa46c69a01afdf4a6cbfd3.us-west1.gcp.cloud.es.io left intact\n 11\":\"rgb(247,251,255)\",\"11 - 22\":\"rgb(208,225,242)\",\"22 - 33\":\"rgb(148,196,223)\",\"33 - 44\":\"rgb(74,152,201)\",\"44 - 55\":\"rgb(23,100,171)\"},\"legendOpen\":false}},\"version\":\"6.3.0\",\"panelRefName\":\"panel_15\"},{\"panelIndex\":\"29\",\"gridData\":{\"x\":40,\"y\":7,\"w\":8,\"h\":6,\"i\":\"29\"},\"embeddableConfig\":{},\"version\":\"6.3.0\",\"panelRefName\":\"panel_16\"},{\"panelIndex\":\"30\",\"gridData\":{\"x\":40,\"y\":13,\"w\":8,\"h\":6,\"i\":\"30\"},\"embeddableConfig\":{},\"version\":\"6.3.0\",\"panelRefName\":\"panel_17\"},{\"panelIndex\":\"31\",\"gridData\":{\"x\":24,\"y\":47,\"w\":24,\"h\":15,\"i\":\"31\"},\"embeddableConfig\":{},\"version\":\"6.3.0\",\"panelRefName\":\"panel_18\"}]", + "optionsJSON": "{\"hidePanelTitles\":false,\"useMargins\":true}", + "version": 1, + "timeRestore": true, + "timeTo": "now", + "timeFrom": "now-24h", + "refreshInterval": { + "display": "15 minutes", + "pause": false, + "section": 2, + "value": 900000 + }, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + } + }, + "references": [ + { + "name": "panel_0", + "type": "visualization", + "id": "aeb212e0-4c84-11e8-b3d7-01146121b73d" + }, + . . . + { + "name": "panel_18", + "type": "visualization", + "id": "ed78a660-53a0-11e8-acbd-0be0ad9d822b" + } + ], + "migrationVersion": { + "dashboard": "7.0.0" + } +} +-------------------------------------------------- diff --git a/docs/api/saved-objects/import.asciidoc b/docs/api/saved-objects/import.asciidoc index 63e733863cc85..1a380830ed21a 100644 --- a/docs/api/saved-objects/import.asciidoc +++ b/docs/api/saved-objects/import.asciidoc @@ -11,8 +11,16 @@ experimental[] Create sets of {kib} saved objects from a file created by the exp `POST /api/saved_objects/_import` +`POST /s//api/saved_objects/_import` + +[[saved-objects-api-import-path-params]] +==== Path parameters + +`space_id`:: + (Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used. + [[saved-objects-api-import-query-params]] -==== Query parameter +==== Query parameters `overwrite`:: (Optional, boolean) Overwrites saved objects. @@ -28,19 +36,19 @@ The request body must include the multipart/form-data type. [[saved-objects-api-import-response-body]] ==== Response body -`success`:: - Top-level property that indicates if the import was successful. +`success`:: + Top-level property that indicates if the import was successful. -`successCount`:: +`successCount`:: Indicates the number of successfully imported records. `errors`:: (array) Indicates the import was unsuccessful and specifies the objects that failed to import. - + [[saved-objects-api-import-codes]] ==== Response code -`200`:: +`200`:: Indicates a successful call. ==== Examples diff --git a/docs/api/saved-objects/resolve_import_errors.asciidoc b/docs/api/saved-objects/resolve_import_errors.asciidoc index b97e5c2a617b0..b64e5deb361b2 100644 --- a/docs/api/saved-objects/resolve_import_errors.asciidoc +++ b/docs/api/saved-objects/resolve_import_errors.asciidoc @@ -4,9 +4,9 @@ Resolve import errors ++++ -experimental[] Resolve errors from the import API. +experimental[] Resolve errors from the import API. -To resolve errors, you can: +To resolve errors, you can: * Retry certain saved objects @@ -19,6 +19,14 @@ To resolve errors, you can: `POST /api/saved_objects/_resolve_import_errors` +`POST /s//api/saved_objects/_resolve_import_errors` + +[[saved-objects-api-resolve-import-errors-path-params]] +==== Path parameters + +`space_id`:: + (Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used. + [[saved-objects-api-resolve-import-errors-request-body]] ==== Request body @@ -33,19 +41,19 @@ The request body must include the multipart/form-data type. [[saved-objects-api-resolve-import-errors-response-body]] ==== Response body -`success`:: +`success`:: Top-level property that indicates if the errors successfully resolved. - -`successCount`:: + +`successCount`:: Indicates the number of successfully resolved records. `errors`:: (array) Specifies the objects that failed to resolve. - + [[saved-objects-api-resolve-import-errors-codes]] ==== Response code -`200`:: +`200`:: Indicates a successful call. [[saved-objects-api-resolve-import-errors-example]] diff --git a/docs/api/saved-objects/update.asciidoc b/docs/api/saved-objects/update.asciidoc index 5c4bb98d09228..99a9bd4ad15bb 100644 --- a/docs/api/saved-objects/update.asciidoc +++ b/docs/api/saved-objects/update.asciidoc @@ -11,8 +11,13 @@ experimental[] Update the attributes for existing {kib} saved objects. `PUT /api/saved_objects//` +`PUT /s//api/saved_objects//` + [[saved-objects-api-update-path-params]] -==== Path Parameters +==== Path parameters + +`space_id`:: + (Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used. `type`:: (Required, string) Valid options include `visualization`, `dashboard`, `search`, `index-pattern`, `config`, and `timelion-sheet`. @@ -21,7 +26,7 @@ experimental[] Update the attributes for existing {kib} saved objects. (Required, string) The object ID to update. [[saved-objects-api-update-request-body]] -==== Request Body +==== Request body `attributes`:: (Required, object) The data to persist. @@ -30,11 +35,11 @@ WARNING: When you update, attributes are not validated, which allows you to pass `references`:: (Optional, array) Objects with `name`, `id`, and `type` properties that describe the other saved objects this object references. To refer to the other saved object, use `name` in the attributes, but never the `id`, which automatically updates during migrations or import/export. - + [[saved-objects-api-update-errors-codes]] ==== Response code -`200`:: +`200`:: Indicates a successful call. [[saved-objects-api-update-example]] diff --git a/docs/development/core/public/kibana-plugin-core-public.app.mount.md b/docs/development/core/public/kibana-plugin-core-public.app.mount.md index c42f73ced95af..8a9dfd9e2e972 100644 --- a/docs/development/core/public/kibana-plugin-core-public.app.mount.md +++ b/docs/development/core/public/kibana-plugin-core-public.app.mount.md @@ -14,5 +14,5 @@ mount: AppMount | AppMountDeprecated ## Remarks -When function has two arguments, it will be called with a [context](./kibana-plugin-core-public.appmountcontext.md) as the first argument. This behavior is \*\*deprecated\*\*, and consumers should instead use [CoreSetup.getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md). +When function has two arguments, it will be called with a [context](./kibana-plugin-core-public.appmountcontext.md) as the first argument. This behavior is \*\*deprecated\*\*, and consumers should instead use [CoreSetup.getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md). diff --git a/docs/development/core/public/kibana-plugin-core-public.applicationsetup.md b/docs/development/core/public/kibana-plugin-core-public.applicationsetup.md index e5554be515077..fc99e2208220f 100644 --- a/docs/development/core/public/kibana-plugin-core-public.applicationsetup.md +++ b/docs/development/core/public/kibana-plugin-core-public.applicationsetup.md @@ -17,5 +17,5 @@ export interface ApplicationSetup | --- | --- | | [register(app)](./kibana-plugin-core-public.applicationsetup.register.md) | Register an mountable application to the system. | | [registerAppUpdater(appUpdater$)](./kibana-plugin-core-public.applicationsetup.registerappupdater.md) | Register an application updater that can be used to change the [AppUpdatableFields](./kibana-plugin-core-public.appupdatablefields.md) fields of all applications at runtime.This is meant to be used by plugins that needs to updates the whole list of applications. To only updates a specific application, use the updater$ property of the registered application instead. | -| [registerMountContext(contextName, provider)](./kibana-plugin-core-public.applicationsetup.registermountcontext.md) | Register a context provider for application mounting. Will only be available to applications that depend on the plugin that registered this context. Deprecated, use [CoreSetup.getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md). | +| [registerMountContext(contextName, provider)](./kibana-plugin-core-public.applicationsetup.registermountcontext.md) | Register a context provider for application mounting. Will only be available to applications that depend on the plugin that registered this context. Deprecated, use [CoreSetup.getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md). | diff --git a/docs/development/core/public/kibana-plugin-core-public.applicationsetup.registermountcontext.md b/docs/development/core/public/kibana-plugin-core-public.applicationsetup.registermountcontext.md index 92a7ae1c0deee..1735d5df943ae 100644 --- a/docs/development/core/public/kibana-plugin-core-public.applicationsetup.registermountcontext.md +++ b/docs/development/core/public/kibana-plugin-core-public.applicationsetup.registermountcontext.md @@ -8,7 +8,7 @@ > > -Register a context provider for application mounting. Will only be available to applications that depend on the plugin that registered this context. Deprecated, use [CoreSetup.getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md). +Register a context provider for application mounting. Will only be available to applications that depend on the plugin that registered this context. Deprecated, use [CoreSetup.getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md). Signature: diff --git a/docs/development/core/public/kibana-plugin-core-public.applicationstart.md b/docs/development/core/public/kibana-plugin-core-public.applicationstart.md index 834411de5d57c..a93bc61bac527 100644 --- a/docs/development/core/public/kibana-plugin-core-public.applicationstart.md +++ b/docs/development/core/public/kibana-plugin-core-public.applicationstart.md @@ -24,5 +24,5 @@ export interface ApplicationStart | --- | --- | | [getUrlForApp(appId, options)](./kibana-plugin-core-public.applicationstart.geturlforapp.md) | Returns an URL to a given app, including the global base path. By default, the URL is relative (/basePath/app/my-app). Use the absolute option to generate an absolute url (http://host:port/basePath/app/my-app)Note that when generating absolute urls, the protocol, host and port are determined from the browser location. | | [navigateToApp(appId, options)](./kibana-plugin-core-public.applicationstart.navigatetoapp.md) | Navigate to a given app | -| [registerMountContext(contextName, provider)](./kibana-plugin-core-public.applicationstart.registermountcontext.md) | Register a context provider for application mounting. Will only be available to applications that depend on the plugin that registered this context. Deprecated, use [CoreSetup.getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md). | +| [registerMountContext(contextName, provider)](./kibana-plugin-core-public.applicationstart.registermountcontext.md) | Register a context provider for application mounting. Will only be available to applications that depend on the plugin that registered this context. Deprecated, use [CoreSetup.getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md). | diff --git a/docs/development/core/public/kibana-plugin-core-public.applicationstart.registermountcontext.md b/docs/development/core/public/kibana-plugin-core-public.applicationstart.registermountcontext.md index 6e0fbb46e9a1e..11f661c4af2b3 100644 --- a/docs/development/core/public/kibana-plugin-core-public.applicationstart.registermountcontext.md +++ b/docs/development/core/public/kibana-plugin-core-public.applicationstart.registermountcontext.md @@ -8,7 +8,7 @@ > > -Register a context provider for application mounting. Will only be available to applications that depend on the plugin that registered this context. Deprecated, use [CoreSetup.getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md). +Register a context provider for application mounting. Will only be available to applications that depend on the plugin that registered this context. Deprecated, use [CoreSetup.getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md). Signature: diff --git a/docs/development/core/public/kibana-plugin-core-public.appmountcontext.md b/docs/development/core/public/kibana-plugin-core-public.appmountcontext.md index d0b243859aab0..52a36b0b56f02 100644 --- a/docs/development/core/public/kibana-plugin-core-public.appmountcontext.md +++ b/docs/development/core/public/kibana-plugin-core-public.appmountcontext.md @@ -8,7 +8,7 @@ > > -The context object received when applications are mounted to the DOM. Deprecated, use [CoreSetup.getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md). +The context object received when applications are mounted to the DOM. Deprecated, use [CoreSetup.getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md). Signature: diff --git a/docs/development/core/public/kibana-plugin-core-public.appmountdeprecated.md b/docs/development/core/public/kibana-plugin-core-public.appmountdeprecated.md index 130689882495a..66b8a69d84a38 100644 --- a/docs/development/core/public/kibana-plugin-core-public.appmountdeprecated.md +++ b/docs/development/core/public/kibana-plugin-core-public.appmountdeprecated.md @@ -18,5 +18,5 @@ export declare type AppMountDeprecated = (contex ## Remarks -When function has two arguments, it will be called with a [context](./kibana-plugin-core-public.appmountcontext.md) as the first argument. This behavior is \*\*deprecated\*\*, and consumers should instead use [CoreSetup.getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md). +When function has two arguments, it will be called with a [context](./kibana-plugin-core-public.appmountcontext.md) as the first argument. This behavior is \*\*deprecated\*\*, and consumers should instead use [CoreSetup.getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md). diff --git a/docs/development/core/public/kibana-plugin-core-public.coresetup.getstartservices.md b/docs/development/core/public/kibana-plugin-core-public.coresetup.getstartservices.md index 91b906cf83d01..e4fec4eae31b1 100644 --- a/docs/development/core/public/kibana-plugin-core-public.coresetup.getstartservices.md +++ b/docs/development/core/public/kibana-plugin-core-public.coresetup.getstartservices.md @@ -2,16 +2,12 @@ [Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [CoreSetup](./kibana-plugin-core-public.coresetup.md) > [getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md) -## CoreSetup.getStartServices() method +## CoreSetup.getStartServices property -Allows plugins to get access to APIs available in start inside async handlers, such as [App.mount](./kibana-plugin-core-public.app.mount.md). Promise will not resolve until Core and plugin dependencies have completed `start`. +[StartServicesAccessor](./kibana-plugin-core-public.startservicesaccessor.md) Signature: ```typescript -getStartServices(): Promise<[CoreStart, TPluginsStart]>; +getStartServices: StartServicesAccessor; ``` -Returns: - -`Promise<[CoreStart, TPluginsStart]>` - diff --git a/docs/development/core/public/kibana-plugin-core-public.coresetup.md b/docs/development/core/public/kibana-plugin-core-public.coresetup.md index f211b740e84a3..c039bc19348cc 100644 --- a/docs/development/core/public/kibana-plugin-core-public.coresetup.md +++ b/docs/development/core/public/kibana-plugin-core-public.coresetup.md @@ -19,14 +19,9 @@ export interface CoreSetup | [application](./kibana-plugin-core-public.coresetup.application.md) | ApplicationSetup | [ApplicationSetup](./kibana-plugin-core-public.applicationsetup.md) | | [context](./kibana-plugin-core-public.coresetup.context.md) | ContextSetup | [ContextSetup](./kibana-plugin-core-public.contextsetup.md) | | [fatalErrors](./kibana-plugin-core-public.coresetup.fatalerrors.md) | FatalErrorsSetup | [FatalErrorsSetup](./kibana-plugin-core-public.fatalerrorssetup.md) | +| [getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md) | StartServicesAccessor<TPluginsStart> | [StartServicesAccessor](./kibana-plugin-core-public.startservicesaccessor.md) | | [http](./kibana-plugin-core-public.coresetup.http.md) | HttpSetup | [HttpSetup](./kibana-plugin-core-public.httpsetup.md) | | [injectedMetadata](./kibana-plugin-core-public.coresetup.injectedmetadata.md) | {
getInjectedVar: (name: string, defaultValue?: any) => unknown;
} | exposed temporarily until https://github.com/elastic/kibana/issues/41990 done use \*only\* to retrieve config values. There is no way to set injected values in the new platform. Use the legacy platform API instead. | | [notifications](./kibana-plugin-core-public.coresetup.notifications.md) | NotificationsSetup | [NotificationsSetup](./kibana-plugin-core-public.notificationssetup.md) | | [uiSettings](./kibana-plugin-core-public.coresetup.uisettings.md) | IUiSettingsClient | [IUiSettingsClient](./kibana-plugin-core-public.iuisettingsclient.md) | -## Methods - -| Method | Description | -| --- | --- | -| [getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md) | Allows plugins to get access to APIs available in start inside async handlers, such as [App.mount](./kibana-plugin-core-public.app.mount.md). Promise will not resolve until Core and plugin dependencies have completed start. | - diff --git a/docs/development/core/public/kibana-plugin-core-public.md b/docs/development/core/public/kibana-plugin-core-public.md index b8aa56eb2941b..adc87de2b9e7e 100644 --- a/docs/development/core/public/kibana-plugin-core-public.md +++ b/docs/development/core/public/kibana-plugin-core-public.md @@ -38,7 +38,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [AppLeaveDefaultAction](./kibana-plugin-core-public.appleavedefaultaction.md) | Action to return from a [AppLeaveHandler](./kibana-plugin-core-public.appleavehandler.md) to execute the default behaviour when leaving the application.See | | [ApplicationSetup](./kibana-plugin-core-public.applicationsetup.md) | | | [ApplicationStart](./kibana-plugin-core-public.applicationstart.md) | | -| [AppMountContext](./kibana-plugin-core-public.appmountcontext.md) | The context object received when applications are mounted to the DOM. Deprecated, use [CoreSetup.getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md). | +| [AppMountContext](./kibana-plugin-core-public.appmountcontext.md) | The context object received when applications are mounted to the DOM. Deprecated, use [CoreSetup.getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md). | | [AppMountParameters](./kibana-plugin-core-public.appmountparameters.md) | | | [Capabilities](./kibana-plugin-core-public.capabilities.md) | The read-only set of capabilities available for the current UI session. Capabilities are simple key-value pairs of (string, boolean), where the string denotes the capability ID, and the boolean is a flag indicating if the capability is enabled or disabled. | | [ChromeBadge](./kibana-plugin-core-public.chromebadge.md) | | @@ -153,6 +153,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [SavedObjectAttribute](./kibana-plugin-core-public.savedobjectattribute.md) | Type definition for a Saved Object attribute value | | [SavedObjectAttributeSingle](./kibana-plugin-core-public.savedobjectattributesingle.md) | Don't use this type, it's simply a helper type for [SavedObjectAttribute](./kibana-plugin-core-public.savedobjectattribute.md) | | [SavedObjectsClientContract](./kibana-plugin-core-public.savedobjectsclientcontract.md) | SavedObjectsClientContract as implemented by the [SavedObjectsClient](./kibana-plugin-core-public.savedobjectsclient.md) | +| [StartServicesAccessor](./kibana-plugin-core-public.startservicesaccessor.md) | Allows plugins to get access to APIs available in start inside async handlers, such as [App.mount](./kibana-plugin-core-public.app.mount.md). Promise will not resolve until Core and plugin dependencies have completed start. | | [StringValidation](./kibana-plugin-core-public.stringvalidation.md) | Allows regex objects or a regex string | | [Toast](./kibana-plugin-core-public.toast.md) | | | [ToastInput](./kibana-plugin-core-public.toastinput.md) | Inputs for [IToasts](./kibana-plugin-core-public.itoasts.md) APIs. | diff --git a/docs/development/core/public/kibana-plugin-core-public.startservicesaccessor.md b/docs/development/core/public/kibana-plugin-core-public.startservicesaccessor.md new file mode 100644 index 0000000000000..02e896a6b47e5 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.startservicesaccessor.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [StartServicesAccessor](./kibana-plugin-core-public.startservicesaccessor.md) + +## StartServicesAccessor type + +Allows plugins to get access to APIs available in start inside async handlers, such as [App.mount](./kibana-plugin-core-public.app.mount.md). Promise will not resolve until Core and plugin dependencies have completed `start`. + +Signature: + +```typescript +export declare type StartServicesAccessor = () => Promise<[CoreStart, TPluginsStart]>; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.coresetup.getstartservices.md b/docs/development/core/server/kibana-plugin-core-server.coresetup.getstartservices.md index 10a656363c0d0..ea8e610ee56de 100644 --- a/docs/development/core/server/kibana-plugin-core-server.coresetup.getstartservices.md +++ b/docs/development/core/server/kibana-plugin-core-server.coresetup.getstartservices.md @@ -2,16 +2,12 @@ [Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreSetup](./kibana-plugin-core-server.coresetup.md) > [getStartServices](./kibana-plugin-core-server.coresetup.getstartservices.md) -## CoreSetup.getStartServices() method +## CoreSetup.getStartServices property -Allows plugins to get access to APIs available in start inside async handlers. Promise will not resolve until Core and plugin dependencies have completed `start`. This should only be used inside handlers registered during `setup` that will only be executed after `start` lifecycle. +[StartServicesAccessor](./kibana-plugin-core-server.startservicesaccessor.md) Signature: ```typescript -getStartServices(): Promise<[CoreStart, TPluginsStart]>; +getStartServices: StartServicesAccessor; ``` -Returns: - -`Promise<[CoreStart, TPluginsStart]>` - diff --git a/docs/development/core/server/kibana-plugin-core-server.coresetup.md b/docs/development/core/server/kibana-plugin-core-server.coresetup.md index 5b5803629cc86..b0eba8ac78063 100644 --- a/docs/development/core/server/kibana-plugin-core-server.coresetup.md +++ b/docs/development/core/server/kibana-plugin-core-server.coresetup.md @@ -19,15 +19,10 @@ export interface CoreSetup | [capabilities](./kibana-plugin-core-server.coresetup.capabilities.md) | CapabilitiesSetup | [CapabilitiesSetup](./kibana-plugin-core-server.capabilitiessetup.md) | | [context](./kibana-plugin-core-server.coresetup.context.md) | ContextSetup | [ContextSetup](./kibana-plugin-core-server.contextsetup.md) | | [elasticsearch](./kibana-plugin-core-server.coresetup.elasticsearch.md) | ElasticsearchServiceSetup | [ElasticsearchServiceSetup](./kibana-plugin-core-server.elasticsearchservicesetup.md) | +| [getStartServices](./kibana-plugin-core-server.coresetup.getstartservices.md) | StartServicesAccessor<TPluginsStart> | [StartServicesAccessor](./kibana-plugin-core-server.startservicesaccessor.md) | | [http](./kibana-plugin-core-server.coresetup.http.md) | HttpServiceSetup | [HttpServiceSetup](./kibana-plugin-core-server.httpservicesetup.md) | | [metrics](./kibana-plugin-core-server.coresetup.metrics.md) | MetricsServiceSetup | [MetricsServiceSetup](./kibana-plugin-core-server.metricsservicesetup.md) | | [savedObjects](./kibana-plugin-core-server.coresetup.savedobjects.md) | SavedObjectsServiceSetup | [SavedObjectsServiceSetup](./kibana-plugin-core-server.savedobjectsservicesetup.md) | | [uiSettings](./kibana-plugin-core-server.coresetup.uisettings.md) | UiSettingsServiceSetup | [UiSettingsServiceSetup](./kibana-plugin-core-server.uisettingsservicesetup.md) | | [uuid](./kibana-plugin-core-server.coresetup.uuid.md) | UuidServiceSetup | [UuidServiceSetup](./kibana-plugin-core-server.uuidservicesetup.md) | -## Methods - -| Method | Description | -| --- | --- | -| [getStartServices()](./kibana-plugin-core-server.coresetup.getstartservices.md) | Allows plugins to get access to APIs available in start inside async handlers. Promise will not resolve until Core and plugin dependencies have completed start. This should only be used inside handlers registered during setup that will only be executed after start lifecycle. | - diff --git a/docs/development/core/server/kibana-plugin-core-server.md b/docs/development/core/server/kibana-plugin-core-server.md index 54cf496b2d6af..a1158dc853918 100644 --- a/docs/development/core/server/kibana-plugin-core-server.md +++ b/docs/development/core/server/kibana-plugin-core-server.md @@ -259,6 +259,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [SavedObjectsFieldMapping](./kibana-plugin-core-server.savedobjectsfieldmapping.md) | Describe a [saved object type mapping](./kibana-plugin-core-server.savedobjectstypemappingdefinition.md) field.Please refer to [elasticsearch documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html) For the mapping documentation | | [ScopeableRequest](./kibana-plugin-core-server.scopeablerequest.md) | A user credentials container. It accommodates the necessary auth credentials to impersonate the current user.See [KibanaRequest](./kibana-plugin-core-server.kibanarequest.md). | | [SharedGlobalConfig](./kibana-plugin-core-server.sharedglobalconfig.md) | | +| [StartServicesAccessor](./kibana-plugin-core-server.startservicesaccessor.md) | Allows plugins to get access to APIs available in start inside async handlers. Promise will not resolve until Core and plugin dependencies have completed start. This should only be used inside handlers registered during setup that will only be executed after start lifecycle. | | [StringValidation](./kibana-plugin-core-server.stringvalidation.md) | Allows regex objects or a regex string | | [UiSettingsType](./kibana-plugin-core-server.uisettingstype.md) | UI element type to represent the settings. | diff --git a/docs/development/core/server/kibana-plugin-core-server.startservicesaccessor.md b/docs/development/core/server/kibana-plugin-core-server.startservicesaccessor.md new file mode 100644 index 0000000000000..4de781fc99cc1 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.startservicesaccessor.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [StartServicesAccessor](./kibana-plugin-core-server.startservicesaccessor.md) + +## StartServicesAccessor type + +Allows plugins to get access to APIs available in start inside async handlers. Promise will not resolve until Core and plugin dependencies have completed `start`. This should only be used inside handlers registered during `setup` that will only be executed after `start` lifecycle. + +Signature: + +```typescript +export declare type StartServicesAccessor = () => Promise<[CoreStart, TPluginsStart]>; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.enabled.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.enabled.md new file mode 100644 index 0000000000000..2ef8c797f4054 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.enabled.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) > [enabled](./kibana-plugin-plugins-data-public.aggconfigoptions.enabled.md) + +## AggConfigOptions.enabled property + +Signature: + +```typescript +enabled?: boolean; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.id.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.id.md new file mode 100644 index 0000000000000..8939854ab19ca --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) > [id](./kibana-plugin-plugins-data-public.aggconfigoptions.id.md) + +## AggConfigOptions.id property + +Signature: + +```typescript +id?: string; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.md new file mode 100644 index 0000000000000..b841d9b04d6a7 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) + +## AggConfigOptions interface + +Signature: + +```typescript +export interface AggConfigOptions +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [enabled](./kibana-plugin-plugins-data-public.aggconfigoptions.enabled.md) | boolean | | +| [id](./kibana-plugin-plugins-data-public.aggconfigoptions.id.md) | string | | +| [params](./kibana-plugin-plugins-data-public.aggconfigoptions.params.md) | Record<string, any> | | +| [schema](./kibana-plugin-plugins-data-public.aggconfigoptions.schema.md) | string | | +| [type](./kibana-plugin-plugins-data-public.aggconfigoptions.type.md) | IAggType | | + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.params.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.params.md new file mode 100644 index 0000000000000..45219a837cc33 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.params.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) > [params](./kibana-plugin-plugins-data-public.aggconfigoptions.params.md) + +## AggConfigOptions.params property + +Signature: + +```typescript +params?: Record; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.schema.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.schema.md new file mode 100644 index 0000000000000..b2b42eb2e5b4d --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.schema.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) > [schema](./kibana-plugin-plugins-data-public.aggconfigoptions.schema.md) + +## AggConfigOptions.schema property + +Signature: + +```typescript +schema?: string; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.type.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.type.md new file mode 100644 index 0000000000000..866065ce52ba6 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) > [type](./kibana-plugin-plugins-data-public.aggconfigoptions.type.md) + +## AggConfigOptions.type property + +Signature: + +```typescript +type: IAggType; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.es_field_types.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.es_field_types.md index e7341caf7b3cd..c5e01715534d1 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.es_field_types.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.es_field_types.md @@ -30,6 +30,7 @@ export declare enum ES_FIELD_TYPES | GEO\_POINT | "geo_point" | | | GEO\_SHAPE | "geo_shape" | | | HALF\_FLOAT | "half_float" | | +| HISTOGRAM | "histogram" | | | INTEGER | "integer" | | | IP | "ip" | | | KEYWORD | "keyword" | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md index e5ae8ffbd2877..30c3aa946c1ce 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md @@ -23,6 +23,7 @@ export declare enum KBN_FIELD_TYPES | DATE | "date" | | | GEO\_POINT | "geo_point" | | | GEO\_SHAPE | "geo_shape" | | +| HISTOGRAM | "histogram" | | | IP | "ip" | | | MURMUR3 | "murmur3" | | | NESTED | "nested" | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md index f8516ec476e88..ea77d6f39389b 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md @@ -48,6 +48,7 @@ | Interface | Description | | --- | --- | +| [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) | | | [AggParamOption](./kibana-plugin-plugins-data-public.aggparamoption.md) | | | [DataPublicPluginSetup](./kibana-plugin-plugins-data-public.datapublicpluginsetup.md) | | | [DataPublicPluginStart](./kibana-plugin-plugins-data-public.datapublicpluginstart.md) | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.es_field_types.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.es_field_types.md index 81a7cbca77c48..d071955f4f522 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.es_field_types.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.es_field_types.md @@ -30,6 +30,7 @@ export declare enum ES_FIELD_TYPES | GEO\_POINT | "geo_point" | | | GEO\_SHAPE | "geo_shape" | | | HALF\_FLOAT | "half_float" | | +| HISTOGRAM | "histogram" | | | INTEGER | "integer" | | | IP | "ip" | | | KEYWORD | "keyword" | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md index 40b81d2f6ac4d..a0a64190497c8 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md @@ -23,6 +23,7 @@ export declare enum KBN_FIELD_TYPES | DATE | "date" | | | GEO\_POINT | "geo_point" | | | GEO\_SHAPE | "geo_shape" | | +| HISTOGRAM | "histogram" | | | IP | "ip" | | | MURMUR3 | "murmur3" | | | NESTED | "nested" | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md index d179b9d9dcd82..e756eb9b72905 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md @@ -60,6 +60,7 @@ | [esQuery](./kibana-plugin-plugins-data-server.esquery.md) | | | [fieldFormats](./kibana-plugin-plugins-data-server.fieldformats.md) | | | [indexPatterns](./kibana-plugin-plugins-data-server.indexpatterns.md) | | +| [search](./kibana-plugin-plugins-data-server.search.md) | | ## Type Aliases @@ -69,5 +70,6 @@ | [IFieldFormatsRegistry](./kibana-plugin-plugins-data-server.ifieldformatsregistry.md) | | | [ISearch](./kibana-plugin-plugins-data-server.isearch.md) | | | [ISearchCancel](./kibana-plugin-plugins-data-server.isearchcancel.md) | | +| [ParsedInterval](./kibana-plugin-plugins-data-server.parsedinterval.md) | | | [TSearchStrategyProvider](./kibana-plugin-plugins-data-server.tsearchstrategyprovider.md) | Search strategy provider creates an instance of a search strategy with the request handler context bound to it. This way every search strategy can use whatever information they require from the request context. | diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index 385b3af2ba4a4..b3437dfca2768 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -200,7 +200,7 @@ that feature would not take any effect. `logging.rotate.everyBytes:`:: [experimental] *Default: 10485760* The maximum size of a log file (that is `not an exact` limit). After the limit is reached, a new log file is generated. The default size limit is 10485760 (10 MB) and -this option should be in the range of 102400 (100KB) to 1073741824 (1GB). +this option should be in the range of 1048576 (1 MB) to 1073741824 (1 GB). `logging.rotate.keepFiles:`:: [experimental] *Default: 7* The number of most recent rotated log files to keep on disk. Older files are deleted during log rotation. The default value is 7. The `logging.rotate.keepFiles` @@ -210,7 +210,7 @@ option has to be in the range of 2 to 1024 files. the `logging.rotate.usePolling` is enabled. That option has to be in the range of 5000 to 3600000 milliseconds. `logging.rotate.usePolling:`:: [experimental] *Default: false* By default we try to understand the best way to monitoring -the log file. However, there is some systems where it could not be always accurate. In those cases, if needed, +the log file and warning about it. Please be aware there are some systems where watch api is not accurate. In those cases, in order to get the feature working, the `polling` method could be used enabling that option. `logging.silent:`:: *Default: false* Set the value of this setting to `true` to diff --git a/package.json b/package.json index ac70640271b29..f156c432ab03e 100644 --- a/package.json +++ b/package.json @@ -187,7 +187,7 @@ "hjson": "3.2.1", "hoek": "^5.0.4", "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.2", + "https-proxy-agent": "^5.0.0", "immer": "^1.5.0", "inert": "^5.1.0", "inline-style": "^2.0.0", @@ -343,7 +343,7 @@ "@types/lru-cache": "^5.1.0", "@types/markdown-it": "^0.0.7", "@types/minimatch": "^2.0.29", - "@types/mocha": "^5.2.7", + "@types/mocha": "^7.0.2", "@types/moment-timezone": "^0.5.12", "@types/mustache": "^0.8.31", "@types/node": ">=10.17.17 <10.20.0", @@ -450,7 +450,7 @@ "license-checker": "^16.0.0", "listr": "^0.14.1", "load-grunt-config": "^3.0.1", - "mocha": "^6.2.2", + "mocha": "^7.1.1", "mock-http-server": "1.3.0", "multistream": "^2.1.1", "murmurhash3js": "3.0.1", diff --git a/packages/kbn-ui-shared-deps/monaco.ts b/packages/kbn-ui-shared-deps/monaco.ts index 570aca86c484c..42801c69a3e2c 100644 --- a/packages/kbn-ui-shared-deps/monaco.ts +++ b/packages/kbn-ui-shared-deps/monaco.ts @@ -25,6 +25,8 @@ import 'monaco-editor/esm/vs/base/worker/defaultWorkerFactory'; import 'monaco-editor/esm/vs/editor/browser/controller/coreCommands.js'; import 'monaco-editor/esm/vs/editor/browser/widget/codeEditorWidget.js'; +import 'monaco-editor/esm/vs/editor/contrib/wordOperations/wordOperations.js'; // Needed for word-wise char navigation + import 'monaco-editor/esm/vs/editor/contrib/suggest/suggestController.js'; // Needed for suggestions import 'monaco-editor/esm/vs/editor/contrib/hover/hover.js'; // Needed for hover import 'monaco-editor/esm/vs/editor/contrib/parameterHints/parameterHints.js'; // Needed for signature diff --git a/src/core/MIGRATION.md b/src/core/MIGRATION.md index 1ca9b63a51d18..0d5d300ec3b79 100644 --- a/src/core/MIGRATION.md +++ b/src/core/MIGRATION.md @@ -1233,11 +1233,11 @@ This table shows where these uiExports have moved to in the New Platform. In mos | `chromeNavControls` | [`core.chrome.navControls.register{Left,Right}`](/docs/development/core/public/kibana-plugin-public.chromenavcontrols.md) | | | `contextMenuActions` | | Should be an API on the devTools plugin. | | `devTools` | | | -| `docViews` | | | +| `docViews` | [`plugins.discover.docViews.addDocView`](./src/plugins/discover/public/doc_views) | Should be an API on the discover plugin. | | `embeddableActions` | | Should be an API on the embeddables plugin. | | `embeddableFactories` | | Should be an API on the embeddables plugin. | -| `fieldFormatEditors` | | | -| `fieldFormats` | [`plugins.data.fieldFormats`](./src/plugins/data/public/field_formats) | | +| `fieldFormatEditors` | | | +| `fieldFormats` | [`plugins.data.fieldFormats`](./src/plugins/data/public/field_formats) | | | `hacks` | n/a | Just run the code in your plugin's `start` method. | | `home` | [`plugins.home.featureCatalogue.register`](./src/plugins/home/public/feature_catalogue) | Must add `home` as a dependency in your kibana.json. | | `indexManagement` | | Should be an API on the indexManagement plugin. | diff --git a/src/core/public/index.ts b/src/core/public/index.ts index 360b254ca50c1..00fd790bf4cc2 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -209,15 +209,21 @@ export interface CoreSetup { injectedMetadata: { getInjectedVar: (name: string, defaultValue?: any) => unknown; }; - - /** - * Allows plugins to get access to APIs available in start inside async - * handlers, such as {@link App.mount}. Promise will not resolve until Core - * and plugin dependencies have completed `start`. - */ - getStartServices(): Promise<[CoreStart, TPluginsStart]>; + /** {@link StartServicesAccessor} */ + getStartServices: StartServicesAccessor; } +/** + * Allows plugins to get access to APIs available in start inside async + * handlers, such as {@link App.mount}. Promise will not resolve until Core + * and plugin dependencies have completed `start`. + * + * @public + */ +export type StartServicesAccessor = () => Promise< + [CoreStart, TPluginsStart] +>; + /** * Core services exposed to the `Plugin` start lifecycle * diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 37212a07ee631..eec12f2348176 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -378,7 +378,8 @@ export interface CoreSetup { context: ContextSetup; // (undocumented) fatalErrors: FatalErrorsSetup; - getStartServices(): Promise<[CoreStart, TPluginsStart]>; + // (undocumented) + getStartServices: StartServicesAccessor; // (undocumented) http: HttpSetup; // @deprecated @@ -1235,6 +1236,9 @@ export class SimpleSavedObject { _version?: SavedObject['version']; } +// @public +export type StartServicesAccessor = () => Promise<[CoreStart, TPluginsStart]>; + // @public export type StringValidation = StringValidationRegex | StringValidationRegexString; diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 89fee92a7ef02..1b436bfd72622 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -352,15 +352,22 @@ export interface CoreSetup { uuid: UuidServiceSetup; /** {@link MetricsServiceSetup} */ metrics: MetricsServiceSetup; - /** - * Allows plugins to get access to APIs available in start inside async handlers. - * Promise will not resolve until Core and plugin dependencies have completed `start`. - * This should only be used inside handlers registered during `setup` that will only be executed - * after `start` lifecycle. - */ - getStartServices(): Promise<[CoreStart, TPluginsStart]>; + /** {@link StartServicesAccessor} */ + getStartServices: StartServicesAccessor; } +/** + * Allows plugins to get access to APIs available in start inside async handlers. + * Promise will not resolve until Core and plugin dependencies have completed `start`. + * This should only be used inside handlers registered during `setup` that will only be executed + * after `start` lifecycle. + * + * @public + */ +export type StartServicesAccessor = () => Promise< + [CoreStart, TPluginsStart] +>; + /** * Context passed to the plugins `start` method. * diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 229ffc4d21575..6d4181e5e1ab3 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -629,7 +629,8 @@ export interface CoreSetup { context: ContextSetup; // (undocumented) elasticsearch: ElasticsearchServiceSetup; - getStartServices(): Promise<[CoreStart, TPluginsStart]>; + // (undocumented) + getStartServices: StartServicesAccessor; // (undocumented) http: HttpServiceSetup; // (undocumented) @@ -2269,6 +2270,9 @@ export type SharedGlobalConfig = RecursiveReadonly_2<{ path: Pick; }>; +// @public +export type StartServicesAccessor = () => Promise<[CoreStart, TPluginsStart]>; + // @public export type StringValidation = StringValidationRegex | StringValidationRegexString; diff --git a/src/legacy/core_plugins/application_usage/mappings.ts b/src/legacy/core_plugins/application_usage/mappings.ts deleted file mode 100644 index 39adc53f7e9ff..0000000000000 --- a/src/legacy/core_plugins/application_usage/mappings.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export const mappings = { - application_usage_totals: { - properties: { - appId: { type: 'keyword' }, - numberOfClicks: { type: 'long' }, - minutesOnScreen: { type: 'float' }, - }, - }, - application_usage_transactional: { - properties: { - timestamp: { type: 'date' }, - appId: { type: 'keyword' }, - numberOfClicks: { type: 'long' }, - minutesOnScreen: { type: 'float' }, - }, - }, -}; diff --git a/src/legacy/core_plugins/application_usage/package.json b/src/legacy/core_plugins/application_usage/package.json deleted file mode 100644 index 5ab10a2f8d237..0000000000000 --- a/src/legacy/core_plugins/application_usage/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "application_usage", - "version": "kibana" -} \ No newline at end of file diff --git a/src/legacy/core_plugins/data/package.json b/src/legacy/core_plugins/data/package.json deleted file mode 100644 index 3f40374650ad7..0000000000000 --- a/src/legacy/core_plugins/data/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "data", - "version": "kibana" -} diff --git a/src/legacy/core_plugins/data/public/legacy.ts b/src/legacy/core_plugins/data/public/legacy.ts deleted file mode 100644 index 370b412127db8..0000000000000 --- a/src/legacy/core_plugins/data/public/legacy.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/** - * New Platform Shim - * - * In this file, we import any legacy dependencies we have, and shim them into - * our plugin by manually constructing the values that the new platform will - * eventually be passing to the `setup` method of our plugin definition. - * - * The idea is that our `plugin.ts` can stay "pure" and not contain any legacy - * world code. Then when it comes time to migrate to the new platform, we can - * simply delete this shim file. - * - * We are also calling `setup` here and exporting our public contract so that - * other legacy plugins are able to import from '../core_plugins/data/legacy' - * and receive the response value of the `setup` contract, mimicking the - * data that will eventually be injected by the new platform. - */ - -import { npSetup, npStart } from 'ui/new_platform'; -import { plugin } from '.'; - -const dataPlugin = plugin(); - -export const setup = dataPlugin.setup(npSetup.core); - -export const start = dataPlugin.start(npStart.core); diff --git a/src/legacy/core_plugins/data/public/plugin.ts b/src/legacy/core_plugins/data/public/plugin.ts deleted file mode 100644 index 76a3d92d20283..0000000000000 --- a/src/legacy/core_plugins/data/public/plugin.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { CoreSetup, CoreStart, Plugin } from 'kibana/public'; - -/** - * Interface for this plugin's returned `setup` contract. - * - * @public - */ -export interface DataSetup {} // eslint-disable-line @typescript-eslint/no-empty-interface - -/** - * Interface for this plugin's returned `start` contract. - * - * @public - */ -export interface DataStart {} // eslint-disable-line @typescript-eslint/no-empty-interface - -/** - * Data Plugin - public - * - * This is the entry point for the entire client-side public contract of the plugin. - * If something is not explicitly exported here, you can safely assume it is private - * to the plugin and not considered stable. - * - * All stateful contracts will be injected by the platform at runtime, and are defined - * in the setup/start interfaces. The remaining items exported here are either types, - * or static code. - */ - -export class DataPlugin implements Plugin { - public setup(core: CoreSetup) { - return {}; - } - - public start(core: CoreStart): DataStart { - return {}; - } - - public stop() {} -} diff --git a/src/legacy/core_plugins/input_control_vis/index.ts b/src/legacy/core_plugins/input_control_vis/index.ts index 8f6178e26126b..d67472ac4b95f 100644 --- a/src/legacy/core_plugins/input_control_vis/index.ts +++ b/src/legacy/core_plugins/input_control_vis/index.ts @@ -25,7 +25,7 @@ import { LegacyPluginApi, LegacyPluginInitializer } from '../../../../src/legacy const inputControlVisPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPluginApi) => new Plugin({ id: 'input_control_vis', - require: ['kibana', 'elasticsearch', 'visualizations', 'interpreter', 'data'], + require: ['kibana', 'elasticsearch', 'visualizations', 'interpreter'], publicDir: resolve(__dirname, 'public'), uiExports: { styleSheetPaths: resolve(__dirname, 'public/index.scss'), diff --git a/src/legacy/core_plugins/input_control_vis/public/input_control_vis_type.ts b/src/legacy/core_plugins/input_control_vis/public/input_control_vis_type.ts index dae6c9abb625e..023e6ebb7125c 100644 --- a/src/legacy/core_plugins/input_control_vis/public/input_control_vis_type.ts +++ b/src/legacy/core_plugins/input_control_vis/public/input_control_vis_type.ts @@ -22,7 +22,6 @@ import { i18n } from '@kbn/i18n'; import { createInputControlVisController } from './vis_controller'; import { getControlsTab } from './components/editor/controls_tab'; import { OptionsTab } from './components/editor/options_tab'; -import { Status } from '../../visualizations/public'; import { InputControlVisDependencies } from './plugin'; import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/common'; @@ -40,7 +39,6 @@ export function createInputControlVisTypeDefinition(deps: InputControlVisDepende defaultMessage: 'Create interactive controls for easy dashboard manipulation.', }), stage: 'experimental', - requiresUpdateStatus: [Status.PARAMS, Status.TIME], feedbackMessage: defaultFeedbackMessage, visualization: InputControlVisController, visConfig: { diff --git a/src/legacy/core_plugins/input_control_vis/public/vis_controller.tsx b/src/legacy/core_plugins/input_control_vis/public/vis_controller.tsx index 624d000dd8d7a..c0ab235c1b9d1 100644 --- a/src/legacy/core_plugins/input_control_vis/public/vis_controller.tsx +++ b/src/legacy/core_plugins/input_control_vis/public/vis_controller.tsx @@ -54,7 +54,7 @@ export const createInputControlVisController = (deps: InputControlVisDependencie .subscribe(this.queryBarUpdateHandler); } - async render(visData: any, visParams: VisParams, status: any) { + async render(visData: any, visParams: VisParams) { this.visParams = visParams; this.controls = []; this.controls = await this.initControls(); diff --git a/src/legacy/core_plugins/kibana/public/.eslintrc.js b/src/legacy/core_plugins/kibana/public/.eslintrc.js index e7171a5291d26..1153706eb8566 100644 --- a/src/legacy/core_plugins/kibana/public/.eslintrc.js +++ b/src/legacy/core_plugins/kibana/public/.eslintrc.js @@ -43,8 +43,6 @@ function buildRestrictedPaths(shimmedPlugins) { 'ui/**/*', 'src/legacy/ui/**/*', 'src/legacy/core_plugins/kibana/public/**/*', - 'src/legacy/core_plugins/data/public/**/*', - '!src/legacy/core_plugins/data/public/index.ts', `!src/legacy/core_plugins/kibana/public/${shimmedPlugin}/**/*`, ], allowSameFolder: false, diff --git a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_app_controller.tsx b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_app_controller.tsx index d1e4c9d2d2a0c..0c6686c993371 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_app_controller.tsx +++ b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_app_controller.tsx @@ -754,7 +754,7 @@ export class DashboardAppController { * When de-angularizing this code, please call the underlaying action function * directly and not via the top nav object. **/ - navActions[TopNavIds.ADD](); + navActions[TopNavIds.ADD_EXISTING](); }; $scope.enterEditMode = () => { dashboardStateManager.setFullScreenMode(false); @@ -847,7 +847,8 @@ export class DashboardAppController { showCloneModal(onClone, currentTitle); }; - navActions[TopNavIds.ADD] = () => { + + navActions[TopNavIds.ADD_EXISTING] = () => { if (dashboardContainer && !isErrorEmbeddable(dashboardContainer)) { openAddPanelFlyout({ embeddable: dashboardContainer, @@ -889,7 +890,8 @@ export class DashboardAppController { share.toggleShareContextMenu({ anchorElement, allowEmbed: true, - allowShortUrl: !dashboardConfig.getHideWriteControls(), + allowShortUrl: + !dashboardConfig.getHideWriteControls() || dashboardCapabilities.createShortUrl, shareableUrl: unhashUrl(window.location.href), objectId: dash.id, objectType: 'dashboard', diff --git a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/get_top_nav_config.ts b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/get_top_nav_config.ts index 7188fab19d6f2..7a3cb4b7dad56 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/get_top_nav_config.ts +++ b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/get_top_nav_config.ts @@ -48,9 +48,10 @@ export function getTopNavConfig( ]; case ViewMode.EDIT: return [ + getCreateNewConfig(actions[TopNavIds.VISUALIZE]), getSaveConfig(actions[TopNavIds.SAVE]), getViewConfig(actions[TopNavIds.EXIT_EDIT_MODE]), - getAddConfig(actions[TopNavIds.ADD]), + getAddConfig(actions[TopNavIds.ADD_EXISTING]), getOptionsConfig(actions[TopNavIds.OPTIONS]), getShareConfig(actions[TopNavIds.SHARE]), ]; @@ -161,6 +162,25 @@ function getAddConfig(action: NavAction) { }; } +/** + * @returns {kbnTopNavConfig} + */ +function getCreateNewConfig(action: NavAction) { + return { + emphasize: true, + iconType: 'plusInCircle', + id: 'addNew', + label: i18n.translate('kbn.dashboard.topNave.addNewButtonAriaLabel', { + defaultMessage: 'Create new', + }), + description: i18n.translate('kbn.dashboard.topNave.addNewConfigDescription', { + defaultMessage: 'Create a new panel on this dashboard', + }), + testId: 'dashboardAddNewPanelButton', + run: action, + }; +} + /** * @returns {kbnTopNavConfig} */ diff --git a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/top_nav_ids.ts b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/top_nav_ids.ts index c67d6891c18e7..748bfaaab6141 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/top_nav_ids.ts +++ b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/top_nav_ids.ts @@ -18,7 +18,6 @@ */ export const TopNavIds = { - ADD: 'add', SHARE: 'share', OPTIONS: 'options', SAVE: 'save', @@ -27,4 +26,5 @@ export const TopNavIds = { CLONE: 'clone', FULL_SCREEN: 'fullScreenMode', VISUALIZE: 'visualize', + ADD_EXISTING: 'addExisting', }; diff --git a/src/legacy/core_plugins/kibana/public/discover/build_services.ts b/src/legacy/core_plugins/kibana/public/discover/build_services.ts index 282eef0c983eb..f881eb96e4e81 100644 --- a/src/legacy/core_plugins/kibana/public/discover/build_services.ts +++ b/src/legacy/core_plugins/kibana/public/discover/build_services.ts @@ -35,10 +35,13 @@ import { import { DiscoverStartPlugins } from './plugin'; import { SharePluginStart } from '../../../../../plugins/share/public'; -import { DocViewsRegistry } from './np_ready/doc_views/doc_views_registry'; import { ChartsPluginStart } from '../../../../../plugins/charts/public'; import { VisualizationsStart } from '../../../visualizations/public'; -import { createSavedSearchesLoader, SavedSearch } from '../../../../../plugins/discover/public'; +import { + createSavedSearchesLoader, + DocViewerComponent, + SavedSearch, +} from '../../../../../plugins/discover/public'; export interface DiscoverServices { addBasePath: (path: string) => string; @@ -47,7 +50,7 @@ export interface DiscoverServices { core: CoreStart; data: DataPublicPluginStart; docLinks: DocLinksStart; - docViewsRegistry: DocViewsRegistry; + DocViewer: DocViewerComponent; history: History; theme: ChartsPluginStart['theme']; filterManager: FilterManager; @@ -64,8 +67,7 @@ export interface DiscoverServices { } export async function buildServices( core: CoreStart, - plugins: DiscoverStartPlugins, - docViewsRegistry: DocViewsRegistry + plugins: DiscoverStartPlugins ): Promise { const services = { savedObjectsClient: core.savedObjects.client, @@ -81,7 +83,7 @@ export async function buildServices( core, data: plugins.data, docLinks: core.docLinks, - docViewsRegistry, + DocViewer: plugins.discover.docViews.DocViewer, history: createHashHistory(), theme: plugins.charts.theme, filterManager: plugins.data.query.filterManager, diff --git a/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts b/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts index cf76a9355e384..7a3a6949baa94 100644 --- a/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts +++ b/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts @@ -52,9 +52,6 @@ export { angular }; export { wrapInI18nContext } from 'ui/i18n'; import { search } from '../../../../../plugins/data/public'; export const { getRequestInspectorStats, getResponseInspectorStats, tabifyAggResponse } = search; -// @ts-ignore -// @ts-ignore -export { timezoneProvider } from 'ui/vis/lib/timezone'; export { unhashUrl, redirectWhenMissing, @@ -78,7 +75,6 @@ export { EsQuerySortValue, SortDirection, } from '../../../../../plugins/data/public'; -export { ElasticSearchHit } from './np_ready/doc_views/doc_views_types'; export { getFormat } from 'ui/visualize/loader/pipeline_helpers/utilities'; // @ts-ignore export { buildPointSeriesData } from 'ui/agg_response/point_series/point_series'; diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name.js index b020113381992..47e50f3cc3d4b 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name.js +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name.js @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { FieldName } from './field_name/field_name'; +import { FieldName } from '../../../../../../../../plugins/discover/public'; import { getServices, wrapInI18nContext } from '../../../kibana_services'; export function FieldNameDirectiveProvider(reactDirective) { diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/histogram.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/histogram.tsx index 107c30ec5e688..f788347ac016c 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/histogram.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/histogram.tsx @@ -42,9 +42,10 @@ import { } from '@elastic/charts'; import { i18n } from '@kbn/i18n'; +import { IUiSettingsClient } from 'kibana/public'; import { EuiChartThemeType } from '@elastic/eui/dist/eui_charts_theme'; import { Subscription } from 'rxjs'; -import { getServices, timezoneProvider } from '../../../kibana_services'; +import { getServices } from '../../../kibana_services'; export interface DiscoverHistogramProps { chartData: any; @@ -86,6 +87,16 @@ function getIntervalInMs( } } +function getTimezone(uiSettings: IUiSettingsClient) { + if (uiSettings.isDefault('dateFormat:tz')) { + const detectedTimezone = moment.tz.guess(); + if (detectedTimezone) return detectedTimezone; + else return moment().format('Z'); + } else { + return uiSettings.get('dateFormat:tz', 'Browser'); + } +} + export function findMinInterval( xValues: number[], esValue: number, @@ -193,7 +204,7 @@ export class DiscoverHistogram extends Component { if (!$scope.vis) return; - return $scope.vis.getAggConfig().onSearchRequestStart(searchSource, options); + return $scope.vis.data.aggs.onSearchRequestStart(searchSource, options); }); $scope.searchSource.setField('aggs', function() { if (!$scope.vis) return; - return $scope.vis.getAggConfig().toDsl(); + return $scope.vis.data.aggs.toDsl(); }); } diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_viewer.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_viewer.tsx similarity index 87% rename from src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_viewer.ts rename to src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_viewer.tsx index 6ba47b839563b..90e061ac1aa05 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_viewer.ts +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_viewer.tsx @@ -17,11 +17,15 @@ * under the License. */ -import { DocViewer } from '../components/doc_viewer/doc_viewer'; +import React from 'react'; +import { getServices } from '../../kibana_services'; export function createDocViewerDirective(reactDirective: any) { return reactDirective( - DocViewer, + (props: any) => { + const { DocViewer } = getServices(); + return ; + }, [ 'hit', ['indexPattern', { watchDepth: 'reference' }], diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/_index.scss b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/_index.scss index 0491430e5fddd..7161560f8fda4 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/_index.scss +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/_index.scss @@ -1,3 +1,2 @@ @import 'fetch_error/index'; @import 'field_chooser/index'; -@import 'doc_viewer/index'; diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.test.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.test.tsx index 2278b243ecc14..1d19dc112d193 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.test.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.test.tsx @@ -24,19 +24,13 @@ import { ReactWrapper } from 'enzyme'; import { findTestSubject } from '@elastic/eui/lib/test'; import { Doc, DocProps } from './doc'; -jest.mock('../doc_viewer/doc_viewer', () => ({ - DocViewer: () => null, -})); - jest.mock('../../../kibana_services', () => { return { getServices: () => ({ metadata: { branch: 'test', }, - getDocViewsSorted: () => { - return []; - }, + DocViewer: () => null, }), }; }); diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.tsx index 819eb9df592bd..28a17dbdb67b7 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.tsx @@ -20,9 +20,9 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiCallOut, EuiLink, EuiLoadingSpinner, EuiPageContent } from '@elastic/eui'; import { IndexPatternsContract } from 'src/plugins/data/public'; -import { DocViewer } from '../doc_viewer/doc_viewer'; import { ElasticRequestState, useEsDocSearch } from './use_es_doc_search'; -import { ElasticSearchHit, getServices } from '../../../kibana_services'; +import { getServices } from '../../../kibana_services'; +import { ElasticSearchHit } from '../../../../../../../../plugins/discover/public'; export interface ElasticSearchResult { hits: { @@ -61,6 +61,7 @@ export interface DocProps { } export function Doc(props: DocProps) { + const { DocViewer } = getServices(); const [reqState, hit, indexPattern] = useEsDocSearch(props); return ( diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/use_es_doc_search.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/use_es_doc_search.ts index 6cffc2cc533b0..2cd264578a596 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/use_es_doc_search.ts +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/use_es_doc_search.ts @@ -17,8 +17,9 @@ * under the License. */ import { useEffect, useState } from 'react'; -import { ElasticSearchHit, IndexPattern } from '../../../kibana_services'; +import { IndexPattern } from '../../../kibana_services'; import { DocProps } from './doc'; +import { ElasticSearchHit } from '../../../../../../../../plugins/discover/public'; export enum ElasticRequestState { Loading, diff --git a/src/legacy/core_plugins/kibana/public/discover/plugin.ts b/src/legacy/core_plugins/kibana/public/discover/plugin.ts index ba671a64592a5..d3cdeb49fba71 100644 --- a/src/legacy/core_plugins/kibana/public/discover/plugin.ts +++ b/src/legacy/core_plugins/kibana/public/discover/plugin.ts @@ -19,7 +19,6 @@ import { BehaviorSubject } from 'rxjs'; import { filter, map } from 'rxjs/operators'; -import { i18n } from '@kbn/i18n'; import { AppMountParameters, CoreSetup, CoreStart, Plugin } from 'kibana/public'; import angular, { auto } from 'angular'; import { UiActionsSetup, UiActionsStart } from 'src/plugins/ui_actions/public'; @@ -41,10 +40,7 @@ import { KibanaLegacySetup, AngularRenderedAppUpdater, } from '../../../../../plugins/kibana_legacy/public'; -import { DocViewsRegistry } from './np_ready/doc_views/doc_views_registry'; -import { DocViewInput, DocViewInputFn } from './np_ready/doc_views/doc_views_types'; -import { DocViewTable } from './np_ready/components/table/table'; -import { JsonCodeBlock } from './np_ready/components/json_code_block/json_code_block'; +import { DiscoverSetup, DiscoverStart } from '../../../../../plugins/discover/public'; import { HomePublicPluginSetup } from '../../../../../plugins/home/public'; import { VisualizationsStart, @@ -52,15 +48,6 @@ import { } from '../../../visualizations/public/np_ready/public'; import { createKbnUrlTracker } from '../../../../../plugins/kibana_utils/public'; -/** - * These are the interfaces with your public contracts. You should export these - * for other plugins to use in _their_ `SetupDeps`/`StartDeps` interfaces. - * @public - */ -export interface DiscoverSetup { - addDocView(docViewRaw: DocViewInput | DocViewInputFn): void; -} -export type DiscoverStart = void; export interface DiscoverSetupPlugins { uiActions: UiActionsSetup; embeddable: EmbeddableSetup; @@ -68,6 +55,7 @@ export interface DiscoverSetupPlugins { home: HomePublicPluginSetup; visualizations: VisualizationsSetup; data: DataPublicPluginSetup; + discover: DiscoverSetup; } export interface DiscoverStartPlugins { uiActions: UiActionsStart; @@ -78,6 +66,7 @@ export interface DiscoverStartPlugins { share: SharePluginStart; inspector: any; visualizations: VisualizationsStart; + discover: DiscoverStart; } const innerAngularName = 'app/discover'; const embeddableAngularName = 'app/discoverEmbeddable'; @@ -87,10 +76,9 @@ const embeddableAngularName = 'app/discoverEmbeddable'; * There are 2 kinds of Angular bootstrapped for rendering, additionally to the main Angular * Discover provides embeddables, those contain a slimmer Angular */ -export class DiscoverPlugin implements Plugin { +export class DiscoverPlugin implements Plugin { private servicesInitialized: boolean = false; private innerAngularInitialized: boolean = false; - private docViewsRegistry: DocViewsRegistry | null = null; private embeddableInjector: auto.IInjectorService | null = null; private getEmbeddableInjector: (() => Promise) | null = null; private appStateUpdater = new BehaviorSubject(() => ({})); @@ -103,7 +91,7 @@ export class DiscoverPlugin implements Plugin { public initializeInnerAngular?: () => void; public initializeServices?: () => Promise<{ core: CoreStart; plugins: DiscoverStartPlugins }>; - setup(core: CoreSetup, plugins: DiscoverSetupPlugins): DiscoverSetup { + setup(core: CoreSetup, plugins: DiscoverSetupPlugins) { const { appMounted, appUnMounted, stop: stopUrlTracker } = createKbnUrlTracker({ baseUrl: core.http.basePath.prepend('/app/kibana'), defaultSubUrl: '#/discover', @@ -130,21 +118,7 @@ export class DiscoverPlugin implements Plugin { }; this.getEmbeddableInjector = this.getInjector.bind(this); - this.docViewsRegistry = new DocViewsRegistry(this.getEmbeddableInjector); - this.docViewsRegistry.addDocView({ - title: i18n.translate('kbn.discover.docViews.table.tableTitle', { - defaultMessage: 'Table', - }), - order: 10, - component: DocViewTable, - }); - this.docViewsRegistry.addDocView({ - title: i18n.translate('kbn.discover.docViews.json.jsonTitle', { - defaultMessage: 'JSON', - }), - order: 20, - component: JsonCodeBlock, - }); + plugins.discover.docViews.setAngularInjectorGetter(this.getEmbeddableInjector); plugins.kibanaLegacy.registerLegacyApp({ id: 'discover', title: 'Discover', @@ -172,14 +146,10 @@ export class DiscoverPlugin implements Plugin { }, }); registerFeature(plugins.home); - this.registerEmbeddable(core, plugins); - return { - addDocView: this.docViewsRegistry.addDocView.bind(this.docViewsRegistry), - }; } - start(core: CoreStart, plugins: DiscoverStartPlugins): DiscoverStart { + start(core: CoreStart, plugins: DiscoverStartPlugins) { // we need to register the application service at setup, but to render it // there are some start dependencies necessary, for this reason // initializeInnerAngular + initializeServices are assigned at start and used @@ -198,7 +168,7 @@ export class DiscoverPlugin implements Plugin { if (this.servicesInitialized) { return { core, plugins }; } - const services = await buildServices(core, plugins, this.docViewsRegistry!); + const services = await buildServices(core, plugins); setServices(services); this.servicesInitialized = true; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/__jest__/__snapshots__/relationships.test.js.snap b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/__jest__/__snapshots__/relationships.test.js.snap index c1241d5d7c1e5..728944f3ccbfe 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/__jest__/__snapshots__/relationships.test.js.snap +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/__jest__/__snapshots__/relationships.test.js.snap @@ -53,6 +53,7 @@ exports[`Relationships should render dashboards normally 1`] = ` "width": "50px", }, Object { + "data-test-subj": "directRelationship", "dataType": "string", "field": "relationship", "name": "Direct relationship", @@ -72,6 +73,7 @@ exports[`Relationships should render dashboards normally 1`] = ` "actions": Array [ Object { "available": [Function], + "data-test-subj": "relationshipsTableAction-inspect", "description": "Inspect this saved object", "icon": "inspect", "name": "Inspect", @@ -117,6 +119,7 @@ exports[`Relationships should render dashboards normally 1`] = ` } pagination={true} responsive={true} + rowProps={[Function]} search={ Object { "filters": Array [ @@ -263,6 +266,7 @@ exports[`Relationships should render index patterns normally 1`] = ` "width": "50px", }, Object { + "data-test-subj": "directRelationship", "dataType": "string", "field": "relationship", "name": "Direct relationship", @@ -282,6 +286,7 @@ exports[`Relationships should render index patterns normally 1`] = ` "actions": Array [ Object { "available": [Function], + "data-test-subj": "relationshipsTableAction-inspect", "description": "Inspect this saved object", "icon": "inspect", "name": "Inspect", @@ -327,6 +332,7 @@ exports[`Relationships should render index patterns normally 1`] = ` } pagination={true} responsive={true} + rowProps={[Function]} search={ Object { "filters": Array [ @@ -429,6 +435,7 @@ exports[`Relationships should render searches normally 1`] = ` "width": "50px", }, Object { + "data-test-subj": "directRelationship", "dataType": "string", "field": "relationship", "name": "Direct relationship", @@ -448,6 +455,7 @@ exports[`Relationships should render searches normally 1`] = ` "actions": Array [ Object { "available": [Function], + "data-test-subj": "relationshipsTableAction-inspect", "description": "Inspect this saved object", "icon": "inspect", "name": "Inspect", @@ -493,6 +501,7 @@ exports[`Relationships should render searches normally 1`] = ` } pagination={true} responsive={true} + rowProps={[Function]} search={ Object { "filters": Array [ @@ -595,6 +604,7 @@ exports[`Relationships should render visualizations normally 1`] = ` "width": "50px", }, Object { + "data-test-subj": "directRelationship", "dataType": "string", "field": "relationship", "name": "Direct relationship", @@ -614,6 +624,7 @@ exports[`Relationships should render visualizations normally 1`] = ` "actions": Array [ Object { "available": [Function], + "data-test-subj": "relationshipsTableAction-inspect", "description": "Inspect this saved object", "icon": "inspect", "name": "Inspect", @@ -659,6 +670,7 @@ exports[`Relationships should render visualizations normally 1`] = ` } pagination={true} responsive={true} + rowProps={[Function]} search={ Object { "filters": Array [ diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/relationships.js b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/relationships.js index ee9fb70e31fb2..ce3415ad2f0e7 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/relationships.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/relationships.js @@ -135,6 +135,7 @@ export class Relationships extends Component { aria-label={getSavedObjectLabel(type)} type={object.meta.icon || 'apps'} size="s" + data-test-subj="relationshipsObjectType" /> ); @@ -149,6 +150,7 @@ export class Relationships extends Component { dataType: 'string', sortable: false, width: '125px', + 'data-test-subj': 'directRelationship', render: relationship => { if (relationship === 'parent') { return ( @@ -187,10 +189,16 @@ export class Relationships extends Component { const { path } = object.meta.inAppUrl || {}; const canGoInApp = this.props.canGoInApp(object); if (!canGoInApp) { - return {title || getDefaultTitle(object)}; + return ( + + {title || getDefaultTitle(object)} + + ); } return ( - {title || getDefaultTitle(object)} + + {title || getDefaultTitle(object)} + ); }, }, @@ -211,6 +219,7 @@ export class Relationships extends Component { ), type: 'icon', icon: 'inspect', + 'data-test-subj': 'relationshipsTableAction-inspect', onClick: object => goInspectObject(object), available: object => !!object.meta.editUrl, }, @@ -295,6 +304,9 @@ export class Relationships extends Component { columns={columns} pagination={true} search={search} + rowProps={() => ({ + 'data-test-subj': `relationshipsTableRow`, + })} /> ); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/table.js b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/table.js index 386b35399b754..5342693113bca 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/table.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/table.js @@ -186,6 +186,7 @@ export class Table extends PureComponent { aria-label={getSavedObjectLabel(type)} type={object.meta.icon || 'apps'} size="s" + data-test-subj="objectType" /> ); diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/breadcrumbs.ts b/src/legacy/core_plugins/kibana/public/visualize/np_ready/breadcrumbs.ts index c334172805b9f..b6a63d50b205b 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/breadcrumbs.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/breadcrumbs.ts @@ -69,7 +69,7 @@ export function getEditBreadcrumbs($route: any) { return [ ...getLandingBreadcrumbs(), { - text: $route.current.locals.savedVis.title, + text: $route.current.locals.resolved.savedVis.title, }, ]; } diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.html b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.html index 28baf21925cbe..0dcacd30fba4e 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.html +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.html @@ -69,7 +69,8 @@ diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js index 7d1c29fbf48da..c5325ca3108b4 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js @@ -22,6 +22,7 @@ import _ from 'lodash'; import { Subscription } from 'rxjs'; import { map } from 'rxjs/operators'; import { i18n } from '@kbn/i18n'; +import { EventEmitter } from 'events'; import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -84,6 +85,7 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState uiSettings, I18nContext, setActiveUrl, + visualizations, } = getServices(); const { @@ -98,27 +100,63 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState ); // Retrieve the resolved SavedVis instance. - const savedVis = $route.current.locals.savedVis; + const { vis, savedVis, savedSearch, embeddableHandler } = $route.current.locals.resolved; + $scope.eventEmitter = new EventEmitter(); const _applyVis = () => { $scope.$apply(); }; // This will trigger a digest cycle. This is needed when vis is updated from a global angular like in visualize_embeddable.js. - savedVis.vis.on('apply', _applyVis); + $scope.eventEmitter.on('apply', _applyVis); // vis is instance of src/legacy/ui/public/vis/vis.js. // SearchSource is a promise-based stream of search results that can inherit from other search sources. - const { vis, searchSource, savedSearch } = savedVis; + const searchSource = vis.data.searchSource; $scope.vis = vis; + $scope.savedSearch = savedSearch; const $appStatus = { dirty: !savedVis.id, }; - vis.on('dirtyStateChange', ({ isDirty }) => { - vis.dirty = isDirty; - $scope.$digest(); + const defaultQuery = { + query: '', + language: + localStorage.get('kibana.userQueryLanguage') || uiSettings.get('search:queryLanguage'), + }; + + const visStateToEditorState = () => { + const savedVisState = visualizations.convertFromSerializedVis(vis.serialize()); + return { + uiState: vis.uiState.toJSON(), + query: vis.data.searchSource.getOwnField('query') || defaultQuery, + filters: vis.data.searchSource.getOwnField('filter') || [], + vis: { ...savedVisState.visState, title: vis.title }, + linked: !!savedVis.savedSearchId, + }; + }; + + const stateDefaults = visStateToEditorState(); + + const { stateContainer, stopStateSync } = useVisualizeAppState({ + stateDefaults, + kbnUrlStateStorage, + }); + + $scope.eventEmitter.on('dirtyStateChange', ({ isDirty }) => { + if (!isDirty) { + stateContainer.transitions.updateVisState(visStateToEditorState().vis); + } + $timeout(() => { + $scope.dirty = isDirty; + }); + }); + + $scope.eventEmitter.on('updateVis', () => { + embeddableHandler.reload(); }); + $scope.embeddableHandler = embeddableHandler; + $scope.topNavMenu = [ ...(visualizeCapabilities.save ? [ @@ -135,10 +173,10 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState ), testId: 'visualizeSaveButton', disableButton() { - return Boolean(vis.dirty); + return Boolean($scope.dirty); }, tooltip() { - if (vis.dirty) { + if ($scope.dirty) { return i18n.translate( 'kbn.visualize.topNavMenu.saveVisualizationDisabledButtonTooltip', { @@ -207,7 +245,7 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState }), testId: 'shareTopNavButton', run: anchorElement => { - const hasUnappliedChanges = vis.dirty; + const hasUnappliedChanges = $scope.dirty; const hasUnsavedChanges = $appStatus.dirty; share.toggleShareContextMenu({ anchorElement, @@ -233,17 +271,17 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState }), testId: 'openInspectorButton', disableButton() { - return !vis.hasInspector || !vis.hasInspector(); + return !embeddableHandler.hasInspector || !embeddableHandler.hasInspector(); }, run() { - const inspectorSession = vis.openInspector(); + const inspectorSession = embeddableHandler.openInspector(); // Close the inspector if this scope is destroyed (e.g. because the user navigates away). const removeWatch = $scope.$on('$destroy', () => inspectorSession.close()); // Remove that watch in case the user closes the inspector session herself. inspectorSession.onClose.finally(removeWatch); }, tooltip() { - if (!vis.hasInspector || !vis.hasInspector()) { + if (!embeddableHandler.hasInspector || !embeddableHandler.hasInspector()) { return i18n.translate('kbn.visualize.topNavMenu.openInspectorDisabledButtonTooltip', { defaultMessage: `This visualization doesn't support any inspectors.`, }); @@ -257,7 +295,7 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState defaultMessage: 'Refresh', }), run: function() { - vis.forceReload(); + embeddableHandler.reload(); }, testId: 'visualizeRefreshButton', }, @@ -267,28 +305,6 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState chrome.docTitle.change(savedVis.title); } - const defaultQuery = { - query: '', - language: - localStorage.get('kibana.userQueryLanguage') || uiSettings.get('search:queryLanguage'), - }; - - // Extract visualization state with filtered aggs. You can see these filtered aggs in the URL. - // Consists of things like aggs, params, listeners, title, type, etc. - const savedVisState = vis.getState(); - const stateDefaults = { - uiState: savedVis.uiStateJSON ? JSON.parse(savedVis.uiStateJSON) : {}, - query: searchSource.getOwnField('query') || defaultQuery, - filters: searchSource.getOwnField('filter') || [], - vis: savedVisState, - linked: !!savedVis.savedSearchId, - }; - - const { stateContainer, stopStateSync } = useVisualizeAppState({ - stateDefaults, - kbnUrlStateStorage, - }); - // sync initial app filters from state to filterManager filterManager.setAppFilters(_.cloneDeep(stateContainer.getState().filters)); // setup syncing of app filters between appState and filterManager @@ -315,7 +331,8 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState // appState then they won't be equal. if (!_.isEqual(stateContainer.getState().vis, stateDefaults.vis)) { try { - vis.setState(stateContainer.getState().vis); + const { aggs, ...visState } = stateContainer.getState().vis; + vis.setState({ ...visState, data: { aggs } }); } catch (error) { // stop syncing url updtes with the state to prevent extra syncing stopAllSyncing(); @@ -369,8 +386,8 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState }; function init() { - if (vis.indexPattern) { - $scope.indexPattern = vis.indexPattern; + if (vis.data.indexPattern) { + $scope.indexPattern = vis.data.indexPattern; } else { indexPatterns.getDefault().then(defaultIndexPattern => { $scope.indexPattern = defaultIndexPattern; @@ -379,22 +396,14 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState const initialState = stateContainer.getState(); - $scope.appState = { - // mock implementation of the legacy appState.save() - // this could be even replaced by passing only "updateAppState" callback - save() { - stateContainer.transitions.updateVisState(vis.getState()); - }, - }; - const handleLinkedSearch = linked => { if (linked && !savedVis.savedSearchId && savedSearch) { savedVis.savedSearchId = savedSearch.id; - vis.savedSearchId = savedSearch.id; + vis.data.savedSearchId = savedSearch.id; searchSource.setParent(savedSearch.searchSource); } else if (!linked && savedVis.savedSearchId) { delete savedVis.savedSearchId; - delete vis.savedSearchId; + delete vis.data.savedSearchId; } }; @@ -403,6 +412,7 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState 'uiState', stateContainer ); + vis.uiState = persistedState; $scope.uiState = persistedState; $scope.savedVis = savedVis; $scope.query = initialState.query; @@ -427,7 +437,7 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState $scope.showQueryBarTimePicker = () => { // tsvb loads without an indexPattern initially (TODO investigate). // hide timefilter only if timeFieldName is explicitly undefined. - const hasTimeField = vis.indexPattern ? !!vis.indexPattern.timeFieldName : true; + const hasTimeField = vis.data.indexPattern ? !!vis.data.indexPattern.timeFieldName : true; return vis.type.options.showTimePicker && hasTimeField; }; @@ -442,10 +452,24 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState updateSavedQueryFromUrl(state.savedQuery); // if the browser history was changed manually we need to reflect changes in the editor - if (!_.isEqual(vis.getState(), state.vis)) { - vis.setState(state.vis); - vis.forceReload(); - vis.emit('updateEditor'); + if ( + !_.isEqual( + { + ...visualizations.convertFromSerializedVis(vis.serialize()).visState, + title: vis.title, + }, + state.vis + ) + ) { + const { aggs, ...visState } = state.vis; + vis.setState({ + ...visState, + data: { + aggs, + }, + }); + embeddableHandler.reload(); + $scope.eventEmitter.emit('updateEditor'); } $appStatus.dirty = true; @@ -498,8 +522,8 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState const { query, linked, filters } = stateContainer.getState(); $scope.query = query; handleLinkedSearch(linked); - savedVis.searchSource.setField('query', query); - savedVis.searchSource.setField('filter', filters); + vis.data.searchSource.setField('query', query); + vis.data.searchSource.setField('filter', filters); $scope.$broadcast('render'); }; @@ -533,7 +557,7 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState } savedVis.destroy(); subscriptions.unsubscribe(); - $scope.vis.off('apply', _applyVis); + $scope.eventEmitter.off('apply', _applyVis); unsubscribePersisted(); unsubscribeStateUpdates(); @@ -556,7 +580,7 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState // If nothing has changed, trigger the fetch manually, otherwise it will happen as a result of the changes if (!isUpdate) { - $scope.vis.forceReload(); + embeddableHandler.reload(); } }; @@ -605,8 +629,10 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState title: savedVis.title, type: savedVis.type || stateContainer.getState().vis.type, }); + savedVis.searchSource.setField('query', stateContainer.getState().query); + savedVis.searchSource.setField('filter', stateContainer.getState().filters); savedVis.visState = stateContainer.getState().vis; - savedVis.uiStateJSON = angular.toJson($scope.uiState.getChanges()); + savedVis.uiStateJSON = angular.toJson($scope.uiState.toJSON()); $appStatus.dirty = false; return savedVis.save(saveOptions).then( @@ -720,7 +746,7 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState ); }; - vis.on('unlinkFromSavedSearch', unlinkFromSavedSearch); + $scope.eventEmitter.on('unlinkFromSavedSearch', unlinkFromSavedSearch); addHelpMenuToAppChrome(chrome, docLinks); diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization.js b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization.js index c8acea168444f..fbabd6fc87c98 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization.js +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization.js @@ -17,12 +17,12 @@ * under the License. */ -export function initVisualizationDirective(app, deps) { +export function initVisualizationDirective(app) { app.directive('visualizationEmbedded', function($timeout) { return { restrict: 'E', scope: { - savedObj: '=', + embeddableHandler: '=', uiState: '=?', timeRange: '=', filters: '=', @@ -31,24 +31,16 @@ export function initVisualizationDirective(app, deps) { }, link: function($scope, element) { $scope.renderFunction = async () => { - if (!$scope._handler) { - $scope._handler = await deps.embeddable - .getEmbeddableFactory('visualization') - .createFromObject($scope.savedObj, { - timeRange: $scope.timeRange, - filters: $scope.filters || [], - query: $scope.query, - appState: $scope.appState, - uiState: $scope.uiState, - }); - $scope._handler.render(element[0]); - } else { - $scope._handler.updateInput({ - timeRange: $scope.timeRange, - filters: $scope.filters || [], - query: $scope.query, - }); + if (!$scope.rendered) { + $scope.embeddableHandler.render(element[0]); + $scope.rendered = true; } + + $scope.embeddableHandler.updateInput({ + timeRange: $scope.timeRange, + filters: $scope.filters || [], + query: $scope.query, + }); }; $scope.$on('render', event => { @@ -59,8 +51,8 @@ export function initVisualizationDirective(app, deps) { }); $scope.$on('$destroy', () => { - if ($scope._handler) { - $scope._handler.destroy(); + if ($scope.embeddableHandler) { + $scope.embeddableHandler.destroy(); } }); }, diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js index f2d9cbe2ad84c..ef174dbaa5865 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js @@ -22,16 +22,23 @@ export function initVisEditorDirective(app, deps) { return { restrict: 'E', scope: { - savedObj: '=', + vis: '=', uiState: '=?', timeRange: '=', filters: '=', query: '=', - appState: '=', + savedSearch: '=', + embeddableHandler: '=', + eventEmitter: '=', }, link: function($scope, element) { - const Editor = $scope.savedObj.vis.type.editor || deps.DefaultVisualizationEditor; - const editor = new Editor(element[0], $scope.savedObj); + const Editor = $scope.vis.type.editor || deps.DefaultVisualizationEditor; + const editor = new Editor( + element[0], + $scope.vis, + $scope.eventEmitter, + $scope.embeddableHandler + ); $scope.renderFunction = () => { editor.render({ @@ -42,8 +49,8 @@ export function initVisEditorDirective(app, deps) { timeRange: $scope.timeRange, filters: $scope.filters, query: $scope.query, - appState: $scope.appState, - linked: !!$scope.savedObj.savedSearchId, + linked: !!$scope.vis.data.savedSearchId, + savedSearch: $scope.savedSearch, }); }; diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/legacy_app.js b/src/legacy/core_plugins/kibana/public/visualize/np_ready/legacy_app.js index 0f1d50b149cd9..b0b1ae31a02a5 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/legacy_app.js +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/legacy_app.js @@ -40,6 +40,50 @@ import { getCreateBreadcrumbs, getEditBreadcrumbs, } from './breadcrumbs'; +import { createSavedSearchesLoader } from '../../../../../../plugins/discover/public'; + +const getResolvedResults = deps => { + const { core, data, visualizations } = deps; + + const results = {}; + + return savedVis => { + results.savedVis = savedVis; + return visualizations + .convertToSerializedVis(savedVis) + .then(serializedVis => visualizations.createVis(serializedVis.type, serializedVis)) + .then(vis => { + if (vis.type.setup) { + return vis.type.setup(vis).catch(() => vis); + } + return vis; + }) + .then(vis => { + results.vis = vis; + return deps.embeddable.getEmbeddableFactory('visualization').createFromObject(results.vis, { + timeRange: data.query.timefilter.timefilter.getTime(), + filters: data.query.filterManager.getFilters(), + }); + }) + .then(embeddableHandler => { + results.embeddableHandler = embeddableHandler; + if (results.vis.data.savedSearchId) { + return createSavedSearchesLoader({ + savedObjectsClient: core.savedObjects.client, + indexPatterns: data.indexPatterns, + chrome: core.chrome, + overlays: core.overlays, + }).get(results.vis.data.savedSearchId); + } + }) + .then(savedSearch => { + if (savedSearch) { + results.savedSearch = savedSearch; + } + return results; + }); + }; +}; export function initVisualizeApp(app, deps) { initVisualizeAppDirective(app, deps); @@ -101,7 +145,7 @@ export function initVisualizeApp(app, deps) { template: editorTemplate, k7Breadcrumbs: getCreateBreadcrumbs, resolve: { - savedVis: function($route, history) { + resolved: function($route, history) { const { core, data, savedVisualizations, visualizations, toastNotifications } = deps; const visTypes = visualizations.all(); const visType = find(visTypes, { name: $route.current.params.type }); @@ -121,12 +165,7 @@ export function initVisualizeApp(app, deps) { return ensureDefaultIndexPattern(core, data, history) .then(() => savedVisualizations.get($route.current.params)) - .then(savedVis => { - if (savedVis.vis.type.setup) { - return savedVis.vis.type.setup(savedVis).catch(() => savedVis); - } - return savedVis; - }) + .then(getResolvedResults(deps)) .catch( redirectWhenMissing({ history, @@ -142,20 +181,16 @@ export function initVisualizeApp(app, deps) { template: editorTemplate, k7Breadcrumbs: getEditBreadcrumbs, resolve: { - savedVis: function($route, history) { + resolved: function($route, history) { const { chrome, core, data, savedVisualizations, toastNotifications } = deps; + return ensureDefaultIndexPattern(core, data, history) .then(() => savedVisualizations.get($route.current.params.id)) .then(savedVis => { chrome.recentlyAccessed.add(savedVis.getFullPath(), savedVis.title, savedVis.id); return savedVis; }) - .then(savedVis => { - if (savedVis.vis.type.setup) { - return savedVis.vis.type.setup(savedVis).catch(() => savedVis); - } - return savedVis; - }) + .then(getResolvedResults(deps)) .catch( redirectWhenMissing({ history, diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/types.d.ts b/src/legacy/core_plugins/kibana/public/visualize/np_ready/types.d.ts index 01ce872aeb679..246a031f05769 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/types.d.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/types.d.ts @@ -29,8 +29,10 @@ import { PersistedState } from 'src/plugins/visualizations/public'; import { LegacyCoreStart } from 'kibana/public'; import { Vis } from 'src/legacy/core_plugins/visualizations/public'; import { VisSavedObject } from '../legacy_imports'; +import { SavedVisState } from '../../../../visualizations/public/np_ready/public/types'; +import { SavedSearch } from '../../../../../../plugins/discover/public'; -export type PureVisState = ReturnType; +export type PureVisState = SavedVisState; export interface VisualizeAppState { filters: Filter[]; @@ -58,14 +60,13 @@ export interface VisualizeAppStateTransitions { } export interface EditorRenderProps { - appState: { save(): void }; core: LegacyCoreStart; data: DataPublicPluginStart; - embeddable: EmbeddableStart; filters: Filter[]; - uiState: PersistedState; timeRange: TimeRange; query?: Query; + savedSearch?: SavedSearch; + uiState: PersistedState; /** * Flag to determine if visualiztion is linked to the saved search */ diff --git a/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js b/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js index 6bdb5d00e67d8..23ca99791e92e 100644 --- a/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js +++ b/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js @@ -21,7 +21,6 @@ import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import _ from 'lodash'; import ChoroplethLayer from '../choropleth_layer'; -import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern'; import { ImageComparator } from 'test_utils/image_comparator'; import worldJson from './world.json'; import EMS_CATALOGUE from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_manifest.json'; @@ -38,13 +37,11 @@ import afterdatachangePng from './afterdatachange.png'; import afterdatachangeandresizePng from './afterdatachangeandresize.png'; import aftercolorchangePng from './aftercolorchange.png'; import changestartupPng from './changestartup.png'; -import { - setup as visualizationsSetup, - start as visualizationsStart, -} from '../../../visualizations/public/np_ready/public/legacy'; +import { setup as visualizationsSetup } from '../../../visualizations/public/np_ready/public/legacy'; import { createRegionMapVisualization } from '../region_map_visualization'; import { createRegionMapTypeDefinition } from '../region_map_type'; +import { ExprVis } from '../../../visualizations/public/np_ready/public/expressions/vis'; const THRESHOLD = 0.45; const PIXEL_DIFF = 96; @@ -52,7 +49,6 @@ const PIXEL_DIFF = 96; describe('RegionMapsVisualizationTests', function() { let domNode; let RegionMapsVisualization; - let indexPattern; let vis; let dependencies; @@ -115,7 +111,6 @@ describe('RegionMapsVisualizationTests', function() { } RegionMapsVisualization = createRegionMapVisualization(dependencies); - indexPattern = Private(LogstashIndexPatternStubProvider); ChoroplethLayer.prototype._makeJsonAjaxCall = async function() { //simulate network call @@ -158,7 +153,7 @@ describe('RegionMapsVisualizationTests', function() { imageComparator = new ImageComparator(); - vis = visualizationsStart.createVis(indexPattern, { + vis = new ExprVis({ type: 'region_map', }); diff --git a/src/legacy/core_plugins/region_map/public/region_map_type.js b/src/legacy/core_plugins/region_map/public/region_map_type.js index 9a1a76362e094..4faa3f92abb5a 100644 --- a/src/legacy/core_plugins/region_map/public/region_map_type.js +++ b/src/legacy/core_plugins/region_map/public/region_map_type.js @@ -20,7 +20,6 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { mapToLayerWithId } from './util'; import { createRegionMapVisualization } from './region_map_visualization'; -import { Status } from '../../visualizations/public'; import { RegionMapOptions } from './components/region_map_options'; import { truncatedColorSchemas } from '../../../../plugins/charts/public'; import { Schemas } from '../../vis_default_editor/public'; @@ -55,7 +54,6 @@ provided base maps, or add your own. Darker colors represent higher values.', showAllShapes: true, //still under consideration }, }, - requiresUpdateStatus: [Status.AGGS, Status.PARAMS, Status.RESIZE, Status.DATA, Status.UI_STATE], visualization, editorConfig: { optionsTemplate: props => , @@ -100,9 +98,7 @@ provided base maps, or add your own. Darker colors represent higher values.', }, ]), }, - setup: async savedVis => { - const vis = savedVis.vis; - + setup: async vis => { const tmsLayers = await serviceSettings.getTMSServices(); vis.type.editorConfig.collections.tmsLayers = tmsLayers; if (!vis.params.wms.selectedTmsLayer && tmsLayers.length) { @@ -146,7 +142,7 @@ provided base maps, or add your own. Darker colors represent higher values.', vis.params.selectedJoinField = selectedJoinField; } - return savedVis; + return vis; }, }; } diff --git a/src/legacy/core_plugins/region_map/public/region_map_visualization.js b/src/legacy/core_plugins/region_map/public/region_map_visualization.js index 8b5812052a395..25641ea76809d 100644 --- a/src/legacy/core_plugins/region_map/public/region_map_visualization.js +++ b/src/legacy/core_plugins/region_map/public/region_map_visualization.js @@ -39,8 +39,8 @@ export function createRegionMapVisualization({ serviceSettings, $injector, uiSet this._choroplethLayer = null; } - async render(esResponse, visParams, status) { - await super.render(esResponse, visParams, status); + async render(esResponse, visParams) { + await super.render(esResponse, visParams); if (this._choroplethLayer) { await this._choroplethLayer.whenDataLoaded(); } diff --git a/src/legacy/core_plugins/telemetry/common/constants.ts b/src/legacy/core_plugins/telemetry/common/constants.ts deleted file mode 100644 index b44bf319e6627..0000000000000 --- a/src/legacy/core_plugins/telemetry/common/constants.ts +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { i18n } from '@kbn/i18n'; - -/* - * config options opt into telemetry - * @type {string} - */ -export const CONFIG_TELEMETRY = 'telemetry:optIn'; -/* - * config description for opting into telemetry - * @type {string} - */ -export const getConfigTelemetryDesc = () => { - return i18n.translate('telemetry.telemetryConfigDescription', { - defaultMessage: - 'Help us improve the Elastic Stack by providing usage statistics for basic features. We will not share this data outside of Elastic.', - }); -}; - -/** - * The amount of time, in milliseconds, to wait between reports when enabled. - * - * Currently 24 hours. - * @type {Number} - */ -export const REPORT_INTERVAL_MS = 86400000; - -/** - * Link to the Elastic Telemetry privacy statement. - */ -export const PRIVACY_STATEMENT_URL = `https://www.elastic.co/legal/privacy-statement`; - -/** - * The type name used within the Monitoring index to publish localization stats. - * @type {string} - */ -export const KIBANA_LOCALIZATION_STATS_TYPE = 'localization'; - -/** - * The type name used to publish telemetry plugin stats. - * @type {string} - */ -export const TELEMETRY_STATS_TYPE = 'telemetry'; - -/** - * UI metric usage type - * @type {string} - */ -export const UI_METRIC_USAGE_TYPE = 'ui_metric'; - -/** - * Application Usage type - */ -export const APPLICATION_USAGE_TYPE = 'application_usage'; - -/** - * Link to Advanced Settings. - */ -export const PATH_TO_ADVANCED_SETTINGS = 'kibana#/management/kibana/settings'; - -/** - * The type name used within the Monitoring index to publish management stats. - * @type {string} - */ -export const KIBANA_STACK_MANAGEMENT_STATS_TYPE = 'stack_management'; diff --git a/src/legacy/core_plugins/telemetry/index.ts b/src/legacy/core_plugins/telemetry/index.ts deleted file mode 100644 index 1e88e7d65cffd..0000000000000 --- a/src/legacy/core_plugins/telemetry/index.ts +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import * as Rx from 'rxjs'; -import { resolve } from 'path'; -import JoiNamespace from 'joi'; -import { Server } from 'hapi'; -import { PluginInitializerContext } from 'src/core/server'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getConfigPath } from '../../../core/server/path'; -// @ts-ignore -import mappings from './mappings.json'; -import { - telemetryPlugin, - replaceTelemetryInjectedVars, - FetcherTask, - PluginsSetup, - handleOldSettings, -} from './server'; - -const ENDPOINT_VERSION = 'v2'; - -const telemetry = (kibana: any) => { - return new kibana.Plugin({ - id: 'telemetry', - configPrefix: 'telemetry', - publicDir: resolve(__dirname, 'public'), - require: ['elasticsearch'], - config(Joi: typeof JoiNamespace) { - return Joi.object({ - enabled: Joi.boolean().default(true), - allowChangingOptInStatus: Joi.boolean().default(true), - optIn: Joi.when('allowChangingOptInStatus', { - is: false, - then: Joi.valid(true).default(true), - otherwise: Joi.boolean().default(true), - }), - // `config` is used internally and not intended to be set - config: Joi.string().default(getConfigPath()), - banner: Joi.boolean().default(true), - url: Joi.when('$dev', { - is: true, - then: Joi.string().default( - `https://telemetry-staging.elastic.co/xpack/${ENDPOINT_VERSION}/send` - ), - otherwise: Joi.string().default( - `https://telemetry.elastic.co/xpack/${ENDPOINT_VERSION}/send` - ), - }), - optInStatusUrl: Joi.when('$dev', { - is: true, - then: Joi.string().default( - `https://telemetry-staging.elastic.co/opt_in_status/${ENDPOINT_VERSION}/send` - ), - otherwise: Joi.string().default( - `https://telemetry.elastic.co/opt_in_status/${ENDPOINT_VERSION}/send` - ), - }), - sendUsageFrom: Joi.string() - .allow(['server', 'browser']) - .default('browser'), - }).default(); - }, - uiExports: { - managementSections: ['plugins/telemetry/views/management'], - savedObjectSchemas: { - telemetry: { - isNamespaceAgnostic: true, - }, - }, - async replaceInjectedVars(originalInjectedVars: any, request: any, server: any) { - const telemetryInjectedVars = await replaceTelemetryInjectedVars(request, server); - return Object.assign({}, originalInjectedVars, telemetryInjectedVars); - }, - injectDefaultVars(server: Server) { - const config = server.config(); - return { - telemetryEnabled: config.get('telemetry.enabled'), - telemetryUrl: config.get('telemetry.url'), - telemetryBanner: - config.get('telemetry.allowChangingOptInStatus') !== false && - config.get('telemetry.banner'), - telemetryOptedIn: config.get('telemetry.optIn'), - telemetryOptInStatusUrl: config.get('telemetry.optInStatusUrl'), - allowChangingOptInStatus: config.get('telemetry.allowChangingOptInStatus'), - telemetrySendUsageFrom: config.get('telemetry.sendUsageFrom'), - telemetryNotifyUserAboutOptInDefault: false, - }; - }, - mappings, - }, - postInit(server: Server) { - const fetcherTask = new FetcherTask(server); - fetcherTask.start(); - }, - async init(server: Server) { - const { usageCollection } = server.newPlatform.setup.plugins; - const initializerContext = { - env: { - packageInfo: { - version: server.config().get('pkg.version'), - }, - }, - config: { - create() { - const config = server.config(); - return Rx.of({ - enabled: config.get('telemetry.enabled'), - optIn: config.get('telemetry.optIn'), - config: config.get('telemetry.config'), - banner: config.get('telemetry.banner'), - url: config.get('telemetry.url'), - allowChangingOptInStatus: config.get('telemetry.allowChangingOptInStatus'), - }); - }, - }, - } as PluginInitializerContext; - - try { - await handleOldSettings(server); - } catch (err) { - server.log(['warning', 'telemetry'], 'Unable to update legacy telemetry configs.'); - } - - const pluginsSetup: PluginsSetup = { - usageCollection, - }; - - const npPlugin = telemetryPlugin(initializerContext); - await npPlugin.setup(server.newPlatform.setup.core, pluginsSetup, server); - await npPlugin.start(server.newPlatform.start.core); - }, - }); -}; - -// eslint-disable-next-line import/no-default-export -export default telemetry; diff --git a/src/legacy/core_plugins/telemetry/mappings.json b/src/legacy/core_plugins/telemetry/mappings.json deleted file mode 100644 index fa9cc93d6363a..0000000000000 --- a/src/legacy/core_plugins/telemetry/mappings.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "telemetry": { - "properties": { - "enabled": { - "type": "boolean" - }, - "sendUsageFrom": { - "ignore_above": 256, - "type": "keyword" - }, - "lastReported": { - "type": "date" - }, - "lastVersionChecked": { - "ignore_above": 256, - "type": "keyword" - }, - "userHasSeenNotice": { - "type": "boolean" - }, - "reportFailureCount": { - "type": "integer" - }, - "reportFailureVersion": { - "ignore_above": 256, - "type": "keyword" - } - } - } -} diff --git a/src/legacy/core_plugins/telemetry/package.json b/src/legacy/core_plugins/telemetry/package.json deleted file mode 100644 index 979e68cce742f..0000000000000 --- a/src/legacy/core_plugins/telemetry/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "telemetry", - "version": "kibana" -} diff --git a/src/legacy/core_plugins/telemetry/public/views/management/management.tsx b/src/legacy/core_plugins/telemetry/public/views/management/management.tsx deleted file mode 100644 index c8ae410e0aa57..0000000000000 --- a/src/legacy/core_plugins/telemetry/public/views/management/management.tsx +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import React from 'react'; -import routes from 'ui/routes'; -import { npStart, npSetup } from 'ui/new_platform'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { TelemetryManagementSection } from '../../../../../../plugins/telemetry/public/components'; - -routes.defaults(/\/management/, { - resolve: { - telemetryManagementSection() { - const { telemetry } = npStart.plugins as any; - const { advancedSettings } = npSetup.plugins as any; - - if (telemetry && advancedSettings) { - const componentRegistry = advancedSettings.component; - const Component = (props: any) => ( - - ); - - componentRegistry.register( - componentRegistry.componentType.PAGE_FOOTER_COMPONENT, - Component, - true - ); - } - }, - }, -}); diff --git a/src/legacy/core_plugins/telemetry/server/collection_manager.ts b/src/legacy/core_plugins/telemetry/server/collection_manager.ts deleted file mode 100644 index ebac4bede85bb..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/collection_manager.ts +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { encryptTelemetry } from './collectors'; -import { CallCluster } from '../../elasticsearch'; -import { UsageCollectionSetup } from '../../../../plugins/usage_collection/server'; -import { Cluster } from '../../elasticsearch'; -import { ESLicense } from './telemetry_collection/get_local_license'; - -export type EncryptedStatsGetterConfig = { unencrypted: false } & { - server: any; - start: string; - end: string; -}; - -export type UnencryptedStatsGetterConfig = { unencrypted: true } & { - req: any; - start: string; - end: string; -}; - -export interface ClusterDetails { - clusterUuid: string; -} - -export interface StatsCollectionConfig { - usageCollection: UsageCollectionSetup; - callCluster: CallCluster; - server: any; - start: string | number; - end: string | number; -} - -export interface BasicStatsPayload { - timestamp: string; - cluster_uuid: string; - cluster_name: string; - version: string; - cluster_stats: object; - collection?: string; - stack_stats: object; -} - -export type StatsGetterConfig = UnencryptedStatsGetterConfig | EncryptedStatsGetterConfig; -export type ClusterDetailsGetter = (config: StatsCollectionConfig) => Promise; -export type StatsGetter = ( - clustersDetails: ClusterDetails[], - config: StatsCollectionConfig -) => Promise; -export type LicenseGetter = ( - clustersDetails: ClusterDetails[], - config: StatsCollectionConfig -) => Promise<{ [clusterUuid: string]: ESLicense | undefined }>; - -interface CollectionConfig { - title: string; - priority: number; - esCluster: string | Cluster; - statsGetter: StatsGetter; - clusterDetailsGetter: ClusterDetailsGetter; - licenseGetter: LicenseGetter; -} -interface Collection { - statsGetter: StatsGetter; - licenseGetter: LicenseGetter; - clusterDetailsGetter: ClusterDetailsGetter; - esCluster: string | Cluster; - title: string; -} - -export class TelemetryCollectionManager { - private usageGetterMethodPriority = -1; - private collections: Collection[] = []; - - public setCollection = (collectionConfig: CollectionConfig) => { - const { - title, - priority, - esCluster, - statsGetter, - clusterDetailsGetter, - licenseGetter, - } = collectionConfig; - - if (typeof priority !== 'number') { - throw new Error('priority must be set.'); - } - if (priority === this.usageGetterMethodPriority) { - throw new Error(`A Usage Getter with the same priority is already set.`); - } - - if (priority > this.usageGetterMethodPriority) { - if (!statsGetter) { - throw Error('Stats getter method not set.'); - } - if (!esCluster) { - throw Error('esCluster name must be set for the getCluster method.'); - } - if (!clusterDetailsGetter) { - throw Error('Cluster UUIds method is not set.'); - } - if (!licenseGetter) { - throw Error('License getter method not set.'); - } - - this.collections.unshift({ - licenseGetter, - statsGetter, - clusterDetailsGetter, - esCluster, - title, - }); - this.usageGetterMethodPriority = priority; - } - }; - - private getStatsCollectionConfig = async ( - collection: Collection, - config: StatsGetterConfig - ): Promise => { - const { start, end } = config; - const server = config.unencrypted ? config.req.server : config.server; - const { callWithRequest, callWithInternalUser } = - typeof collection.esCluster === 'string' - ? server.plugins.elasticsearch.getCluster(collection.esCluster) - : collection.esCluster; - const callCluster = config.unencrypted - ? (...args: any[]) => callWithRequest(config.req, ...args) - : callWithInternalUser; - - const { usageCollection } = server.newPlatform.setup.plugins; - return { server, callCluster, start, end, usageCollection }; - }; - - private getOptInStatsForCollection = async ( - collection: Collection, - optInStatus: boolean, - statsCollectionConfig: StatsCollectionConfig - ) => { - const clustersDetails = await collection.clusterDetailsGetter(statsCollectionConfig); - return clustersDetails.map(({ clusterUuid }) => ({ - cluster_uuid: clusterUuid, - opt_in_status: optInStatus, - })); - }; - - private getUsageForCollection = async ( - collection: Collection, - statsCollectionConfig: StatsCollectionConfig - ) => { - const clustersDetails = await collection.clusterDetailsGetter(statsCollectionConfig); - - if (clustersDetails.length === 0) { - // don't bother doing a further lookup, try next collection. - return; - } - - const [stats, licenses] = await Promise.all([ - collection.statsGetter(clustersDetails, statsCollectionConfig), - collection.licenseGetter(clustersDetails, statsCollectionConfig), - ]); - - return stats.map(stat => { - const license = licenses[stat.cluster_uuid]; - return { - ...(license ? { license } : {}), - ...stat, - collectionSource: collection.title, - }; - }); - }; - - public getOptInStats = async (optInStatus: boolean, config: StatsGetterConfig) => { - for (const collection of this.collections) { - const statsCollectionConfig = await this.getStatsCollectionConfig(collection, config); - try { - const optInStats = await this.getOptInStatsForCollection( - collection, - optInStatus, - statsCollectionConfig - ); - if (optInStats && optInStats.length) { - statsCollectionConfig.server.log( - ['debug', 'telemetry', 'collection'], - `Got Opt In stats using ${collection.title} collection.` - ); - if (config.unencrypted) { - return optInStats; - } - const isDev = statsCollectionConfig.server.config().get('env.dev'); - return encryptTelemetry(optInStats, isDev); - } - } catch (err) { - statsCollectionConfig.server.log( - ['debu', 'telemetry', 'collection'], - `Failed to collect any opt in stats with registered collections.` - ); - // swallow error to try next collection; - } - } - - return []; - }; - public getStats = async (config: StatsGetterConfig) => { - for (const collection of this.collections) { - const statsCollectionConfig = await this.getStatsCollectionConfig(collection, config); - try { - const usageData = await this.getUsageForCollection(collection, statsCollectionConfig); - if (usageData && usageData.length) { - statsCollectionConfig.server.log( - ['debug', 'telemetry', 'collection'], - `Got Usage using ${collection.title} collection.` - ); - if (config.unencrypted) { - return usageData; - } - const isDev = statsCollectionConfig.server.config().get('env.dev'); - return encryptTelemetry(usageData, isDev); - } - } catch (err) { - statsCollectionConfig.server.log( - ['debug', 'telemetry', 'collection'], - `Failed to collect any usage with registered collections.` - ); - // swallow error to try next collection; - } - } - - return []; - }; -} - -export const telemetryCollectionManager = new TelemetryCollectionManager(); diff --git a/src/legacy/core_plugins/telemetry/server/plugin.ts b/src/legacy/core_plugins/telemetry/server/plugin.ts deleted file mode 100644 index 0b9f0526988c8..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/plugin.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { - CoreSetup, - PluginInitializerContext, - ISavedObjectsRepository, - CoreStart, -} from 'src/core/server'; -import { Server } from 'hapi'; -import { registerRoutes } from './routes'; -import { registerCollection } from './telemetry_collection'; -import { UsageCollectionSetup } from '../../../../plugins/usage_collection/server'; -import { - registerUiMetricUsageCollector, - registerTelemetryUsageCollector, - registerLocalizationUsageCollector, - registerTelemetryPluginUsageCollector, - registerManagementUsageCollector, - registerApplicationUsageCollector, -} from './collectors'; - -export interface PluginsSetup { - usageCollection: UsageCollectionSetup; -} - -export class TelemetryPlugin { - private readonly currentKibanaVersion: string; - private savedObjectsClient?: ISavedObjectsRepository; - - constructor(initializerContext: PluginInitializerContext) { - this.currentKibanaVersion = initializerContext.env.packageInfo.version; - } - - public setup(core: CoreSetup, { usageCollection }: PluginsSetup, server: Server) { - const currentKibanaVersion = this.currentKibanaVersion; - - registerCollection(); - registerRoutes({ core, currentKibanaVersion, server }); - - const getSavedObjectsClient = () => this.savedObjectsClient; - - registerTelemetryPluginUsageCollector(usageCollection, server); - registerLocalizationUsageCollector(usageCollection, server); - registerTelemetryUsageCollector(usageCollection, server); - registerUiMetricUsageCollector(usageCollection, getSavedObjectsClient); - registerManagementUsageCollector(usageCollection, server); - registerApplicationUsageCollector(usageCollection, getSavedObjectsClient); - } - - public start({ savedObjects }: CoreStart) { - this.savedObjectsClient = savedObjects.createInternalRepository(); - } -} diff --git a/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in.ts b/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in.ts deleted file mode 100644 index ccbc28f6cbadb..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in.ts +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import Joi from 'joi'; -import moment from 'moment'; -import { boomify } from 'boom'; -import { CoreSetup } from 'src/core/server'; -import { Legacy } from 'kibana'; -import { getTelemetryAllowChangingOptInStatus } from '../telemetry_config'; -import { sendTelemetryOptInStatus } from './telemetry_opt_in_stats'; - -import { - TelemetrySavedObjectAttributes, - updateTelemetrySavedObject, -} from '../telemetry_repository'; - -interface RegisterOptInRoutesParams { - core: CoreSetup; - currentKibanaVersion: string; - server: Legacy.Server; -} - -export function registerTelemetryOptInRoutes({ - server, - currentKibanaVersion, -}: RegisterOptInRoutesParams) { - server.route({ - method: 'POST', - path: '/api/telemetry/v2/optIn', - options: { - validate: { - payload: Joi.object({ - enabled: Joi.bool().required(), - }), - }, - }, - handler: async (req: any, h: any) => { - try { - const newOptInStatus = req.payload.enabled; - const attributes: TelemetrySavedObjectAttributes = { - enabled: newOptInStatus, - lastVersionChecked: currentKibanaVersion, - }; - const config = req.server.config(); - const savedObjectsClient = req.getSavedObjectsClient(); - const configTelemetryAllowChangingOptInStatus = config.get( - 'telemetry.allowChangingOptInStatus' - ); - - const allowChangingOptInStatus = getTelemetryAllowChangingOptInStatus({ - telemetrySavedObject: savedObjectsClient, - configTelemetryAllowChangingOptInStatus, - }); - if (!allowChangingOptInStatus) { - return h.response({ error: 'Not allowed to change Opt-in Status.' }).code(400); - } - - const sendUsageFrom = config.get('telemetry.sendUsageFrom'); - if (sendUsageFrom === 'server') { - const optInStatusUrl = config.get('telemetry.optInStatusUrl'); - await sendTelemetryOptInStatus( - { optInStatusUrl, newOptInStatus }, - { - start: moment() - .subtract(20, 'minutes') - .toISOString(), - end: moment().toISOString(), - server: req.server, - unencrypted: false, - } - ); - } - - await updateTelemetrySavedObject(savedObjectsClient, attributes); - return h.response({}).code(200); - } catch (err) { - return boomify(err); - } - }, - }); -} diff --git a/src/legacy/core_plugins/telemetry/server/routes/telemetry_usage_stats.ts b/src/legacy/core_plugins/telemetry/server/routes/telemetry_usage_stats.ts deleted file mode 100644 index ee3241b0dc2ea..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/routes/telemetry_usage_stats.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import Joi from 'joi'; -import { boomify } from 'boom'; -import { Legacy } from 'kibana'; -import { telemetryCollectionManager } from '../collection_manager'; - -export function registerTelemetryUsageStatsRoutes(server: Legacy.Server) { - server.route({ - method: 'POST', - path: '/api/telemetry/v2/clusters/_stats', - options: { - validate: { - payload: Joi.object({ - unencrypted: Joi.bool(), - timeRange: Joi.object({ - min: Joi.date().required(), - max: Joi.date().required(), - }).required(), - }), - }, - }, - handler: async (req: any, h: any) => { - const config = req.server.config(); - const start = req.payload.timeRange.min; - const end = req.payload.timeRange.max; - const unencrypted = req.payload.unencrypted; - - try { - return await telemetryCollectionManager.getStats({ - unencrypted, - server, - req, - start, - end, - }); - } catch (err) { - const isDev = config.get('env.dev'); - if (isDev) { - // don't ignore errors when running in dev mode - return boomify(err, { statusCode: err.status || 500 }); - } else { - const statusCode = unencrypted && err.status === 403 ? 403 : 200; - // ignore errors and return empty set - return h.response([]).code(statusCode); - } - } - }, - }); -} diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts deleted file mode 100644 index f09ee8623afac..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { getTelemetrySavedObject } from '../telemetry_repository'; -import { getTelemetryOptIn } from './get_telemetry_opt_in'; -import { getTelemetrySendUsageFrom } from './get_telemetry_send_usage_from'; -import { getTelemetryAllowChangingOptInStatus } from './get_telemetry_allow_changing_opt_in_status'; -import { getNotifyUserAboutOptInDefault } from './get_telemetry_notify_user_about_optin_default'; - -export async function replaceTelemetryInjectedVars(request: any, server: any) { - const config = server.config(); - const configTelemetrySendUsageFrom = config.get('telemetry.sendUsageFrom'); - const configTelemetryOptIn = config.get('telemetry.optIn'); - const configTelemetryAllowChangingOptInStatus = config.get('telemetry.allowChangingOptInStatus'); - const isRequestingApplication = request.path.startsWith('/app'); - - // Prevent interstitial screens (such as the space selector) from prompting for telemetry - if (!isRequestingApplication) { - return { - telemetryOptedIn: false, - }; - } - - const currentKibanaVersion = config.get('pkg.version'); - const savedObjectsClient = server.savedObjects.getScopedSavedObjectsClient(request); - const telemetrySavedObject = await getTelemetrySavedObject(savedObjectsClient); - const allowChangingOptInStatus = getTelemetryAllowChangingOptInStatus({ - configTelemetryAllowChangingOptInStatus, - telemetrySavedObject, - }); - - const telemetryOptedIn = getTelemetryOptIn({ - configTelemetryOptIn, - allowChangingOptInStatus, - telemetrySavedObject, - currentKibanaVersion, - }); - - const telemetrySendUsageFrom = getTelemetrySendUsageFrom({ - configTelemetrySendUsageFrom, - telemetrySavedObject, - }); - - const telemetryNotifyUserAboutOptInDefault = getNotifyUserAboutOptInDefault({ - telemetrySavedObject, - allowChangingOptInStatus, - configTelemetryOptIn, - telemetryOptedIn, - }); - - return { - telemetryOptedIn, - telemetrySendUsageFrom, - telemetryNotifyUserAboutOptInDefault, - }; -} diff --git a/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js b/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js index 6a08405b5b6a5..3b8a7dfbed313 100644 --- a/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js +++ b/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js @@ -19,7 +19,6 @@ import expect from '@kbn/expect'; import ngMock from 'ng_mock'; -import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern'; import { ImageComparator } from 'test_utils/image_comparator'; import dummyESResponse from './dummy_es_response.json'; import initial from './initial.png'; @@ -32,13 +31,11 @@ import EMS_TILES from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_ import EMS_STYLE_ROAD_MAP_BRIGHT from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_bright'; import EMS_STYLE_ROAD_MAP_DESATURATED from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_desaturated'; import EMS_STYLE_DARK_MAP from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_dark'; -import { - setup as visualizationsSetup, - start as visualizationsStart, -} from '../../../visualizations/public/np_ready/public/legacy'; +import { setup as visualizationsSetup } from '../../../visualizations/public/np_ready/public/legacy'; import { createTileMapVisualization } from '../tile_map_visualization'; import { createTileMapTypeDefinition } from '../tile_map_type'; +import { ExprVis } from '../../../visualizations/public/np_ready/public/expressions/vis'; function mockRawData() { const stack = [dummyESResponse]; @@ -67,7 +64,6 @@ let visRegComplete = false; describe('CoordinateMapsVisualizationTest', function() { let domNode; let CoordinateMapsVisualization; - let indexPattern; let vis; let dependencies; @@ -92,7 +88,6 @@ describe('CoordinateMapsVisualizationTest', function() { } CoordinateMapsVisualization = createTileMapVisualization(dependencies); - indexPattern = Private(LogstashIndexPatternStubProvider); getManifestStub = serviceSettings.__debugStubManifestCalls(async url => { //simulate network calls @@ -124,7 +119,7 @@ describe('CoordinateMapsVisualizationTest', function() { setupDOM('512px', '512px'); imageComparator = new ImageComparator(); - vis = visualizationsStart.createVis(indexPattern, { + vis = new ExprVis({ type: 'tile_map', }); vis.params = { diff --git a/src/legacy/core_plugins/tile_map/public/base_maps_visualization.js b/src/legacy/core_plugins/tile_map/public/base_maps_visualization.js index ebb0c24243263..d38159c91ef9f 100644 --- a/src/legacy/core_plugins/tile_map/public/base_maps_visualization.js +++ b/src/legacy/core_plugins/tile_map/public/base_maps_visualization.js @@ -63,28 +63,21 @@ export function BaseMapsVisualizationProvider(serviceSettings) { * @param status * @return {Promise} */ - async render(esResponse, visParams, status) { + async render(esResponse, visParams) { if (!this._kibanaMap) { //the visualization has been destroyed; return; } await this._mapIsLoaded; - - if (status.resize) { - this._kibanaMap.resize(); - } - if (status.params || status.aggs) { - this._params = visParams; - await this._updateParams(); - } + this._kibanaMap.resize(); + this._params = visParams; + await this._updateParams(); if (this._hasESResponseChanged(esResponse)) { await this._updateData(esResponse); } - if (status.uiState) { - this._kibanaMap.useUiStateFromVisualization(this.vis); - } + this._kibanaMap.useUiStateFromVisualization(this.vis); await this._whenBaseLayerIsLoaded(); } diff --git a/src/legacy/core_plugins/tile_map/public/tile_map_type.js b/src/legacy/core_plugins/tile_map/public/tile_map_type.js index 0809bf6ecbab6..39d39a4c8f8fc 100644 --- a/src/legacy/core_plugins/tile_map/public/tile_map_type.js +++ b/src/legacy/core_plugins/tile_map/public/tile_map_type.js @@ -23,7 +23,6 @@ import { i18n } from '@kbn/i18n'; import { convertToGeoJson } from 'ui/vis/map/convert_to_geojson'; import { Schemas } from '../../vis_default_editor/public'; -import { Status } from '../../visualizations/public'; import { createTileMapVisualization } from './tile_map_visualization'; import { TileMapOptions } from './components/tile_map_options'; import { MapTypes } from './map_types'; @@ -57,7 +56,6 @@ export function createTileMapTypeDefinition(dependencies) { wms: uiSettings.get('visualization:tileMap:WMSdefaults'), }, }, - requiresUpdateStatus: [Status.AGGS, Status.PARAMS, Status.RESIZE, Status.UI_STATE], requiresPartialRows: true, visualization: CoordinateMapsVisualization, responseHandler: convertToGeoJson, @@ -143,21 +141,20 @@ export function createTileMapTypeDefinition(dependencies) { }, ]), }, - setup: async savedVis => { - const vis = savedVis.vis; + setup: async vis => { let tmsLayers; try { tmsLayers = await serviceSettings.getTMSServices(); } catch (e) { - return savedVis; + return vis; } vis.type.editorConfig.collections.tmsLayers = tmsLayers; if (!vis.params.wms.selectedTmsLayer && tmsLayers.length) { vis.params.wms.selectedTmsLayer = tmsLayers[0]; } - return savedVis; + return vis; }, }; } diff --git a/src/legacy/core_plugins/timelion/index.ts b/src/legacy/core_plugins/timelion/index.ts index 9e2bfd4023bd9..41a15dc4e0186 100644 --- a/src/legacy/core_plugins/timelion/index.ts +++ b/src/legacy/core_plugins/timelion/index.ts @@ -29,7 +29,7 @@ const experimentalLabel = i18n.translate('timelion.uiSettings.experimentalLabel' const timelionPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPluginApi) => new Plugin({ - require: ['kibana', 'elasticsearch', 'data'], + require: ['kibana', 'elasticsearch'], config(Joi: any) { return Joi.object({ enabled: Joi.boolean().default(true), diff --git a/src/legacy/core_plugins/timelion/public/app.js b/src/legacy/core_plugins/timelion/public/app.js index a9d678cfea79c..a50f8a2cd3e8d 100644 --- a/src/legacy/core_plugins/timelion/public/app.js +++ b/src/legacy/core_plugins/timelion/public/app.js @@ -24,10 +24,10 @@ import { i18n } from '@kbn/i18n'; import { capabilities } from 'ui/capabilities'; import { docTitle } from 'ui/doc_title'; import { fatalError, toastNotifications } from 'ui/notify'; -import { timezoneProvider } from 'ui/vis/lib/timezone'; import { timefilter } from 'ui/timefilter'; import { npStart } from 'ui/new_platform'; import { getSavedSheetBreadcrumbs, getCreateBreadcrumbs } from './breadcrumbs'; +import { getTimezone } from '../../vis_type_timelion/public'; import 'uiExports/savedObjectTypes'; @@ -38,7 +38,6 @@ import 'ui/directives/input_focus'; import './directives/saved_object_finder'; import 'ui/directives/listen'; import './directives/saved_object_save_as_checkbox'; -import '../../data/public/legacy'; import './services/saved_sheet_register'; import rootTemplate from 'plugins/timelion/index.html'; @@ -116,8 +115,7 @@ app.controller('timelion', function( $timeout, AppState, config, - kbnUrl, - Private + kbnUrl ) { // Keeping this at app scope allows us to keep the current page when the user // switches to say, the timepicker. @@ -128,7 +126,7 @@ app.controller('timelion', function( timefilter.enableTimeRangeSelector(); const savedVisualizations = visualizations.savedVisualizationsLoader; - const timezone = Private(timezoneProvider)(); + const timezone = getTimezone(config); const defaultExpression = '.es(*)'; const savedSheet = $route.current.locals.savedSheet; diff --git a/src/legacy/core_plugins/ui_metric/index.ts b/src/legacy/core_plugins/ui_metric/index.ts index 5a4a0ebf1a632..2e5be3d7b0a39 100644 --- a/src/legacy/core_plugins/ui_metric/index.ts +++ b/src/legacy/core_plugins/ui_metric/index.ts @@ -25,9 +25,6 @@ export default function(kibana: any) { id: 'ui_metric', require: ['kibana', 'elasticsearch'], publicDir: resolve(__dirname, 'public'), - uiExports: { - mappings: require('./mappings.json'), - }, init() {}, }); } diff --git a/src/legacy/core_plugins/ui_metric/mappings.json b/src/legacy/core_plugins/ui_metric/mappings.json deleted file mode 100644 index 113e37e60e48b..0000000000000 --- a/src/legacy/core_plugins/ui_metric/mappings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "ui-metric": { - "properties": { - "count": { - "type": "integer" - } - } - } -} diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg.test.tsx index 7e715be25bff3..feb5b3caa023b 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg.test.tsx @@ -22,12 +22,12 @@ import { mount, shallow } from 'enzyme'; import { act } from 'react-dom/test-utils'; import { IndexPattern, IAggType, AggGroupNames } from 'src/plugins/data/public'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { DefaultEditorAgg, DefaultEditorAggProps } from './agg'; import { DefaultEditorAggParams } from './agg_params'; import { AGGS_ACTION_KEYS } from './agg_group_state'; import { Schema } from '../schemas'; +import { EditorVisState } from './sidebar/state/reducers'; jest.mock('./agg_params', () => ({ DefaultEditorAggParams: () => null, @@ -67,7 +67,7 @@ describe('DefaultEditorAgg component', () => { isLastBucket: false, isRemovable: false, metricAggs: [], - state: { params: {} } as VisState, + state: { params: {} } as EditorVisState, setAggParamValue, setStateParamValue, onAggTypeChange: () => {}, diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_common_props.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_common_props.ts index ec92f511b6eee..3aae10879138a 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_common_props.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_common_props.ts @@ -17,9 +17,10 @@ * under the License. */ -import { VisState, VisParams } from 'src/legacy/core_plugins/visualizations/public'; +import { VisParams } from 'src/legacy/core_plugins/visualizations/public'; import { IAggType, IAggConfig, IAggGroupNames } from 'src/plugins/data/public'; import { Schema } from '../schemas'; +import { EditorVisState } from './sidebar/state/reducers'; type AggId = IAggConfig['id']; type AggParams = IAggConfig['params']; @@ -31,7 +32,7 @@ export interface DefaultEditorCommonProps { formIsTouched: boolean; groupName: IAggGroupNames; metricAggs: IAggConfig[]; - state: VisState; + state: EditorVisState; setAggParamValue: ( aggId: AggId, paramName: T, diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.test.tsx index 63f5e696c99f4..5d02f0a2c759e 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.test.tsx @@ -20,12 +20,12 @@ import React from 'react'; import { mount, shallow } from 'enzyme'; import { act } from 'react-dom/test-utils'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { IAggConfigs, IAggConfig } from 'src/plugins/data/public'; import { DefaultEditorAggGroup, DefaultEditorAggGroupProps } from './agg_group'; import { DefaultEditorAgg } from './agg'; import { DefaultEditorAggAdd } from './agg_add'; import { Schema } from '../schemas'; +import { EditorVisState } from './sidebar/state/reducers'; jest.mock('@elastic/eui', () => ({ EuiTitle: 'eui-title', @@ -93,8 +93,8 @@ describe('DefaultEditorAgg component', () => { metricAggs: [], groupName: 'metrics', state: { - aggs, - } as VisState, + data: { aggs }, + } as EditorVisState, schemas: [ { name: 'metrics', @@ -147,8 +147,8 @@ describe('DefaultEditorAgg component', () => { }); expect(reorderAggs).toHaveBeenCalledWith( - defaultProps.state.aggs.aggs[0], - defaultProps.state.aggs.aggs[1] + defaultProps.state.data.aggs!.aggs[0], + defaultProps.state.data.aggs!.aggs[1] ); }); diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx index 600612f2cf9d8..08b69ef37f528 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx @@ -73,9 +73,10 @@ function DefaultEditorAggGroup({ const schemaNames = getSchemasByGroup(schemas, groupName).map(s => s.name); const group: IAggConfig[] = useMemo( () => - state.aggs.aggs.filter((agg: IAggConfig) => agg.schema && schemaNames.includes(agg.schema)) || - [], - [state.aggs.aggs, schemaNames] + state.data.aggs!.aggs.filter( + (agg: IAggConfig) => agg.schema && schemaNames.includes(agg.schema) + ) || [], + [state.data.aggs, schemaNames] ); const stats = { diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts index 7c2852798b403..aec332e8674d7 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts @@ -18,10 +18,10 @@ */ import { IAggConfig, AggParam, IndexPatternField } from 'src/plugins/data/public'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { ComboBoxGroupedOptions } from '../utils'; import { EditorConfig } from './utils'; import { Schema } from '../schemas'; +import { EditorVisState } from './sidebar/state/reducers'; // NOTE: we cannot export the interface with export { InterfaceName } // as there is currently a bug on babel typescript transform plugin for it @@ -35,7 +35,7 @@ export interface AggParamCommonProps { formIsTouched: boolean; indexedFields?: ComboBoxGroupedOptions; showValidation: boolean; - state: VisState; + state: EditorVisState; value?: T; metricAggs: IAggConfig[]; schemas: Schema[]; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx index cd6486b6a1532..1c49ebf40640e 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx @@ -20,7 +20,6 @@ import React from 'react'; import { mount } from 'enzyme'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { IndexPattern, IAggConfig, AggGroupNames } from 'src/plugins/data/public'; import { DefaultEditorAggParams as PureDefaultEditorAggParams, @@ -28,6 +27,7 @@ import { } from './agg_params'; import { KibanaContextProvider } from '../../../../../plugins/kibana_react/public'; import { dataPluginMock } from '../../../../../plugins/data/public/mocks'; +import { EditorVisState } from './sidebar/state/reducers'; const mockEditorConfig = { useNormalizedEsInterval: { hidden: false, fixedValue: false }, @@ -108,7 +108,7 @@ describe('DefaultEditorAggParams component', () => { formIsTouched: false, indexPattern: {} as IndexPattern, metricAggs: [], - state: {} as VisState, + state: {} as EditorVisState, setAggParamValue, onAggTypeChange, setTouched, diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts index f2ebbdc87a60a..bed2561341737 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts @@ -25,7 +25,6 @@ import { IndexPattern, IndexPatternField, } from 'src/plugins/data/public'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { getAggParamsToRender, getAggTypeOptions, @@ -34,6 +33,7 @@ import { import { FieldParamEditor, OrderByParamEditor } from './controls'; import { EditorConfig } from './utils'; import { Schema } from '../schemas'; +import { EditorVisState } from './sidebar/state/reducers'; jest.mock('../utils', () => ({ groupAndSortBy: jest.fn(() => ['indexedFields']), @@ -58,7 +58,7 @@ describe('DefaultEditorAggParams helpers', () => { hideCustomLabel: true, } as Schema, ]; - const state = {} as VisState; + const state = {} as EditorVisState; const metricAggs: IAggConfig[] = []; const emptyParams = { basic: [], diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts index e07bf81697579..10590e1a59f4a 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts @@ -28,7 +28,6 @@ import { IndexPattern, IndexPatternField, } from 'src/plugins/data/public'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { groupAndSortBy, ComboBoxGroupedOptions } from '../utils'; import { AggTypeState, AggParamsState } from './agg_params_state'; import { AggParamEditorProps } from './agg_param_props'; @@ -36,12 +35,13 @@ import { aggParamsMap } from './agg_params_map'; import { EditorConfig } from './utils'; import { Schema, getSchemaByName } from '../schemas'; import { search } from '../../../../../plugins/data/public'; +import { EditorVisState } from './sidebar/state/reducers'; interface ParamInstanceBase { agg: IAggConfig; editorConfig: EditorConfig; metricAggs: IAggConfig[]; - state: VisState; + state: EditorVisState; schemas: Schema[]; hideCustomLabel?: boolean; } diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.test.tsx index 1043431475494..b33149dc51a19 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.test.tsx @@ -23,9 +23,9 @@ import { mount, shallow, ReactWrapper } from 'enzyme'; import { EuiComboBoxProps, EuiComboBox } from '@elastic/eui'; import { IAggConfig, IndexPatternField } from 'src/plugins/data/public'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { ComboBoxGroupedOptions } from '../../utils'; import { FieldParamEditor, FieldParamEditorProps } from './field'; +import { EditorVisState } from '../sidebar/state/reducers'; function callComboBoxOnChange(comp: ReactWrapper, value: any = []) { const comboBoxProps = comp.find(EuiComboBox).props() as EuiComboBoxProps; @@ -78,7 +78,7 @@ describe('FieldParamEditor component', () => { setValue, setValidity, setTouched, - state: {} as VisState, + state: {} as EditorVisState, metricAggs: [] as IAggConfig[], schemas: [], }; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/percentiles.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/percentiles.test.tsx index 76eb12af8c4e2..82166440cf8e8 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/percentiles.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/percentiles.test.tsx @@ -20,9 +20,9 @@ import React from 'react'; import { AggParamEditorProps } from '../agg_param_props'; import { IAggConfig } from 'src/plugins/data/public'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { mount } from 'enzyme'; import { PercentilesEditor } from './percentiles'; +import { EditorVisState } from '../sidebar/state/reducers'; describe('PercentilesEditor component', () => { let setValue: jest.Mock; @@ -45,7 +45,7 @@ describe('PercentilesEditor component', () => { setValue, setValidity, setTouched, - state: {} as VisState, + state: {} as EditorVisState, metricAggs: [] as IAggConfig[], schemas: [], }; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts b/src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts index b816e61cce355..7c7431015d175 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts @@ -17,9 +17,9 @@ * under the License. */ -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { IAggConfig, AggParam } from 'src/plugins/data/public'; import { EditorConfig } from '../utils'; +import { EditorVisState } from '../sidebar/state/reducers'; export const aggParamCommonPropsMock = { agg: {} as IAggConfig, @@ -27,7 +27,7 @@ export const aggParamCommonPropsMock = { editorConfig: {} as EditorConfig, formIsTouched: false, metricAggs: [] as IAggConfig[], - state: {} as VisState, + state: {} as EditorVisState, showValidation: false, schemas: [], }; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/data_tab.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/data_tab.tsx index 6f92c27e90ec1..a6a1980210be4 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/data_tab.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/data_tab.tsx @@ -21,7 +21,6 @@ import React, { useMemo, useCallback } from 'react'; import { findLast } from 'lodash'; import { EuiSpacer } from '@elastic/eui'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { AggGroupNames, IAggConfig, @@ -40,6 +39,7 @@ import { } from './state'; import { AddSchema, ReorderAggs, DefaultEditorAggCommonProps } from '../agg_common_props'; import { ISchemas } from '../../schemas'; +import { EditorVisState } from './state/reducers'; export interface DefaultEditorDataTabProps { dispatch: React.Dispatch; @@ -47,7 +47,7 @@ export interface DefaultEditorDataTabProps { isTabSelected: boolean; metricAggs: IAggConfig[]; schemas: ISchemas; - state: VisState; + state: EditorVisState; setTouched(isTouched: boolean): void; setValidity(modelName: string, value: boolean): void; setStateValue: DefaultEditorAggCommonProps['setStateParamValue']; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx index 2508ef3a55537..04c931f593e5a 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx @@ -21,6 +21,7 @@ import React, { useMemo, useState, useCallback, KeyboardEventHandler, useEffect import { get, isEqual } from 'lodash'; import { i18n } from '@kbn/i18n'; import { keyCodes, EuiButtonIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EventEmitter } from 'events'; import { Vis } from 'src/legacy/core_plugins/visualizations/public'; import { DefaultEditorNavBar, OptionTab } from './navbar'; @@ -40,6 +41,7 @@ interface DefaultEditorSideBarProps { uiState: PersistedState; vis: Vis; isLinkedSearch: boolean; + eventEmitter: EventEmitter; savedSearch?: SavedSearch; } @@ -50,14 +52,17 @@ function DefaultEditorSideBar({ uiState, vis, isLinkedSearch, + eventEmitter, savedSearch, }: DefaultEditorSideBarProps) { const [selectedTab, setSelectedTab] = useState(optionTabs[0].name); const [isDirty, setDirty] = useState(false); - const [state, dispatch] = useEditorReducer(vis); + const [state, dispatch] = useEditorReducer(vis, eventEmitter); const { formState, setTouched, setValidity, resetValidity } = useEditorFormState(); - const responseAggs = useMemo(() => state.aggs.getResponseAggs(), [state.aggs]); + const responseAggs = useMemo(() => (state.data.aggs ? state.data.aggs.getResponseAggs() : []), [ + state.data.aggs, + ]); const metricSchemas = getSchemasByGroup(vis.type.schemas.all || [], AggGroupNames.Metrics).map( s => s.name ); @@ -90,17 +95,20 @@ function DefaultEditorSideBar({ const applyChanges = useCallback(() => { if (formState.invalid || !isDirty) { setTouched(true); - return; } - vis.setCurrentState(state); - vis.updateState(); - vis.emit('dirtyStateChange', { + vis.setState({ + ...vis.serialize(), + params: state.params, + data: { aggs: state.data.aggs ? (state.data.aggs.aggs.map(agg => agg.toJSON()) as any) : [] }, + }); + eventEmitter.emit('updateVis'); + eventEmitter.emit('dirtyStateChange', { isDirty: false, }); setTouched(false); - }, [vis, state, formState.invalid, setTouched, isDirty]); + }, [vis, state, formState.invalid, setTouched, isDirty, eventEmitter]); const onSubmit: KeyboardEventHandler = useCallback( event => { @@ -122,18 +130,22 @@ function DefaultEditorSideBar({ resetValidity(); } }; - vis.on('dirtyStateChange', changeHandler); + eventEmitter.on('dirtyStateChange', changeHandler); - return () => vis.off('dirtyStateChange', changeHandler); - }, [resetValidity, vis]); + return () => { + eventEmitter.off('dirtyStateChange', changeHandler); + }; + }, [resetValidity, eventEmitter]); // subscribe on external vis changes using browser history, for example press back button useEffect(() => { const resetHandler = () => dispatch(discardChanges(vis)); - vis.on('updateEditor', resetHandler); + eventEmitter.on('updateEditor', resetHandler); - return () => vis.off('updateEditor', resetHandler); - }, [dispatch, vis]); + return () => { + eventEmitter.off('updateEditor', resetHandler); + }; + }, [dispatch, vis, eventEmitter]); const dataTabProps = { dispatch, @@ -147,7 +159,7 @@ function DefaultEditorSideBar({ }; const optionTabProps = { - aggs: state.aggs, + aggs: state.data.aggs!, hasHistogramAgg, stateParams: state.params, vis, @@ -173,7 +185,12 @@ function DefaultEditorSideBar({ onKeyDownCapture={onSubmit} > {vis.type.requiresSearch && ( - + )} {optionTabs.length > 1 && ( diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx index 876404851aed4..575ad5ae2a95c 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx @@ -18,6 +18,7 @@ */ import React, { useCallback, useState } from 'react'; +import { EventEmitter } from 'events'; import { EuiButton, EuiButtonEmpty, @@ -39,23 +40,24 @@ import { SavedSearch } from '../../../../../../plugins/discover/public'; interface LinkedSearchProps { savedSearch: SavedSearch; - vis: Vis; + eventEmitter: EventEmitter; } interface SidebarTitleProps { isLinkedSearch: boolean; savedSearch?: SavedSearch; vis: Vis; + eventEmitter: EventEmitter; } -export function LinkedSearch({ savedSearch, vis }: LinkedSearchProps) { +export function LinkedSearch({ savedSearch, eventEmitter }: LinkedSearchProps) { const [showPopover, setShowPopover] = useState(false); const closePopover = useCallback(() => setShowPopover(false), []); const onClickButtonLink = useCallback(() => setShowPopover(v => !v), []); const onClickUnlikFromSavedSearch = useCallback(() => { setShowPopover(false); - vis.emit('unlinkFromSavedSearch'); - }, [vis]); + eventEmitter.emit('unlinkFromSavedSearch'); + }, [eventEmitter]); const linkButtonAriaLabel = i18n.translate( 'visDefaultEditor.sidebar.savedSearch.linkButtonAriaLabel', @@ -151,20 +153,20 @@ export function LinkedSearch({ savedSearch, vis }: LinkedSearchProps) { ); } -function SidebarTitle({ savedSearch, vis, isLinkedSearch }: SidebarTitleProps) { +function SidebarTitle({ savedSearch, vis, isLinkedSearch, eventEmitter }: SidebarTitleProps) { return isLinkedSearch && savedSearch ? ( - + ) : vis.type.options.showIndexSelection ? (

- {vis.indexPattern.title} + {vis.data.indexPattern!.title}

) : ( diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/index.ts b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/index.ts index 6383ac866dcfc..11cbc3f93e9d3 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/index.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/index.ts @@ -17,20 +17,23 @@ * under the License. */ -import { useEffect, useReducer, useCallback } from 'react'; -import { isEqual } from 'lodash'; +import { useReducer, useCallback } from 'react'; +import { EventEmitter } from 'events'; -import { Vis, VisState, VisParams } from 'src/legacy/core_plugins/visualizations/public'; -import { createEditorStateReducer, initEditorState } from './reducers'; +import { Vis } from 'src/legacy/core_plugins/visualizations/public'; +import { createEditorStateReducer, initEditorState, EditorVisState } from './reducers'; import { EditorStateActionTypes } from './constants'; -import { EditorAction, updateStateParams } from './actions'; +import { EditorAction } from './actions'; import { useKibana } from '../../../../../../../plugins/kibana_react/public'; import { VisDefaultEditorKibanaServices } from '../../../types'; export * from './editor_form_state'; export * from './actions'; -export function useEditorReducer(vis: Vis): [VisState, React.Dispatch] { +export function useEditorReducer( + vis: Vis, + eventEmitter: EventEmitter +): [EditorVisState, React.Dispatch] { const { services } = useKibana(); const [state, dispatch] = useReducer( createEditorStateReducer(services.data.search), @@ -38,28 +41,15 @@ export function useEditorReducer(vis: Vis): [VisState, React.Dispatch { - const handleVisUpdate = (params: VisParams) => { - if (!isEqual(params, state.params)) { - dispatch(updateStateParams(params)); - } - }; - - // fires when visualization state changes, and we need to copy changes to editorState - vis.on('updateEditorStateParams', handleVisUpdate); - - return () => vis.off('updateEditorStateParams', handleVisUpdate); - }, [vis, state.params]); - const wrappedDispatch = useCallback( (action: EditorAction) => { dispatch(action); - vis.emit('dirtyStateChange', { + eventEmitter.emit('dirtyStateChange', { isDirty: action.type !== EditorStateActionTypes.DISCARD_CHANGES, }); }, - [vis] + [eventEmitter] ); return [state, wrappedDispatch]; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/reducers.ts b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/reducers.ts index 67220fd9fd91b..6e5bec7c69c90 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/reducers.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/reducers.ts @@ -19,35 +19,45 @@ import { cloneDeep } from 'lodash'; -import { Vis, VisState } from 'src/legacy/core_plugins/visualizations/public'; +import { Vis } from 'src/legacy/core_plugins/visualizations/public'; import { AggGroupNames, DataPublicPluginStart } from '../../../../../../../plugins/data/public'; import { EditorStateActionTypes } from './constants'; import { getEnabledMetricAggsCount } from '../../agg_group_helper'; import { EditorAction } from './actions'; function initEditorState(vis: Vis) { - return vis.copyCurrentState(true); + return { + ...vis.clone(), + }; } +export type EditorVisState = Pick; + const createEditorStateReducer = ({ aggs: { createAggConfigs }, -}: DataPublicPluginStart['search']) => (state: VisState, action: EditorAction): VisState => { +}: DataPublicPluginStart['search']) => ( + state: EditorVisState, + action: EditorAction +): EditorVisState => { switch (action.type) { case EditorStateActionTypes.ADD_NEW_AGG: { const { schema } = action.payload; const defaultConfig = - !state.aggs.aggs.find(agg => agg.schema === schema.name) && schema.defaults + !state.data.aggs!.aggs.find(agg => agg.schema === schema.name) && schema.defaults ? (schema as any).defaults.slice(0, schema.max) : { schema: schema.name }; - const aggConfig = state.aggs.createAggConfig(defaultConfig, { + const aggConfig = state.data.aggs!.createAggConfig(defaultConfig, { addToAggConfigs: false, }); aggConfig.brandNew = true; - const newAggs = [...state.aggs.aggs, aggConfig]; + const newAggs = [...state.data.aggs!.aggs, aggConfig]; return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } @@ -58,7 +68,7 @@ const createEditorStateReducer = ({ case EditorStateActionTypes.CHANGE_AGG_TYPE: { const { aggId, value } = action.payload; - const newAggs = state.aggs.aggs.map(agg => { + const newAggs = state.data.aggs!.aggs.map(agg => { if (agg.id === aggId) { agg.type = value; @@ -70,14 +80,17 @@ const createEditorStateReducer = ({ return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } case EditorStateActionTypes.SET_AGG_PARAM_VALUE: { const { aggId, paramName, value } = action.payload; - const newAggs = state.aggs.aggs.map(agg => { + const newAggs = state.data.aggs!.aggs.map(agg => { if (agg.id === aggId) { const parsedAgg = agg.toJSON(); @@ -95,7 +108,10 @@ const createEditorStateReducer = ({ return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } @@ -113,7 +129,7 @@ const createEditorStateReducer = ({ case EditorStateActionTypes.REMOVE_AGG: { let isMetric = false; - const newAggs = state.aggs.aggs.filter(({ id, schema }) => { + const newAggs = state.data.aggs!.aggs.filter(({ id, schema }) => { if (id === action.payload.aggId) { const schemaDef = action.payload.schemas.find(s => s.name === schema); if (schemaDef && schemaDef.group === AggGroupNames.Metrics) { @@ -136,26 +152,36 @@ const createEditorStateReducer = ({ return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } case EditorStateActionTypes.REORDER_AGGS: { const { sourceAgg, destinationAgg } = action.payload; - const destinationIndex = state.aggs.aggs.indexOf(destinationAgg); - const newAggs = [...state.aggs.aggs]; - newAggs.splice(destinationIndex, 0, newAggs.splice(state.aggs.aggs.indexOf(sourceAgg), 1)[0]); + const destinationIndex = state.data.aggs!.aggs.indexOf(destinationAgg); + const newAggs = [...state.data.aggs!.aggs]; + newAggs.splice( + destinationIndex, + 0, + newAggs.splice(state.data.aggs!.aggs.indexOf(sourceAgg), 1)[0] + ); return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } case EditorStateActionTypes.TOGGLE_ENABLED_AGG: { const { aggId, enabled } = action.payload; - const newAggs = state.aggs.aggs.map(agg => { + const newAggs = state.data.aggs!.aggs.map(agg => { if (agg.id === aggId) { const parsedAgg = agg.toJSON(); @@ -170,7 +196,10 @@ const createEditorStateReducer = ({ return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } diff --git a/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx b/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx index fa3213d244e7e..b504dfd6a55e9 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx @@ -20,10 +20,6 @@ import React, { useEffect, useRef, useState, useCallback } from 'react'; import { EditorRenderProps } from '../../kibana/public/visualize/np_ready/types'; -import { - VisualizeEmbeddableContract as VisualizeEmbeddable, - VisualizeEmbeddableFactoryContract as VisualizeEmbeddableFactory, -} from '../../visualizations/public/'; import { PanelsContainer, Panel } from '../../../../plugins/kibana_react/public'; import './vis_type_agg_filter'; @@ -32,68 +28,44 @@ import { DefaultEditorControllerState } from './default_editor_controller'; import { getInitialWidth } from './editor_size'; function DefaultEditor({ - embeddable, - savedObj, + vis, uiState, timeRange, filters, - appState, optionTabs, query, + embeddableHandler, + eventEmitter, linked, + savedSearch, }: DefaultEditorControllerState & Omit) { const visRef = useRef(null); - const visHandler = useRef(null); const [isCollapsed, setIsCollapsed] = useState(false); - const [factory, setFactory] = useState(null); - const { vis, savedSearch } = savedObj; const onClickCollapse = useCallback(() => { setIsCollapsed(value => !value); }, []); useEffect(() => { - async function visualize() { - if (!visRef.current || (!visHandler.current && factory)) { - return; - } - - if (!visHandler.current) { - const embeddableFactory = embeddable.getEmbeddableFactory( - 'visualization' - ) as VisualizeEmbeddableFactory; - setFactory(embeddableFactory); - - visHandler.current = (await embeddableFactory.createFromObject(savedObj, { - // should be look through createFromObject interface again because of "id" param - id: '', - uiState, - appState, - timeRange, - filters, - query, - })) as VisualizeEmbeddable; - - visHandler.current.render(visRef.current); - } else { - visHandler.current.updateInput({ - timeRange, - filters, - query, - }); - } + if (!visRef.current) { + return; } - visualize(); - }, [uiState, savedObj, timeRange, filters, appState, query, factory, embeddable]); + embeddableHandler.render(visRef.current); + setTimeout(() => { + eventEmitter.emit('apply'); + }); + + return () => embeddableHandler.destroy(); + }, [embeddableHandler, eventEmitter]); useEffect(() => { - return () => { - if (visHandler.current) { - visHandler.current.destroy(); - } - }; - }, []); + embeddableHandler.updateInput({ + timeRange, + filters, + query, + }); + }, [embeddableHandler, timeRange, filters, query]); const editorInitialWidth = getInitialWidth(vis.type.editorConfig.defaultSize); @@ -120,6 +92,7 @@ function DefaultEditor({ uiState={uiState} isLinkedSearch={linked} savedSearch={savedSearch} + eventEmitter={eventEmitter} /> diff --git a/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx b/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx index db910604eddd1..13fcabd799959 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx @@ -21,18 +21,22 @@ import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { i18n } from '@kbn/i18n'; import { I18nProvider } from '@kbn/i18n/react'; +import { EventEmitter } from 'events'; import { EditorRenderProps } from 'src/legacy/core_plugins/kibana/public/visualize/np_ready/types'; -import { VisSavedObject } from 'src/legacy/core_plugins/visualizations/public/'; +import { Vis } from 'src/legacy/core_plugins/visualizations/public/'; import { Storage } from '../../../../plugins/kibana_utils/public'; import { KibanaContextProvider } from '../../../../plugins/kibana_react/public'; import { DefaultEditor } from './default_editor'; import { DefaultEditorDataTab, OptionTab } from './components/sidebar'; +import { VisualizeEmbeddable } from '../../visualizations/public/np_ready/public/embeddable'; const localStorage = new Storage(window.localStorage); export interface DefaultEditorControllerState { - savedObj: VisSavedObject; + vis: Vis; + eventEmitter: EventEmitter; + embeddableHandler: VisualizeEmbeddable; optionTabs: OptionTab[]; } @@ -40,9 +44,9 @@ class DefaultEditorController { private el: HTMLElement; private state: DefaultEditorControllerState; - constructor(el: HTMLElement, savedObj: VisSavedObject) { + constructor(el: HTMLElement, vis: Vis, eventEmitter: EventEmitter, embeddableHandler: any) { this.el = el; - const { type: visType } = savedObj.vis; + const { type: visType } = vis; const optionTabs = [ ...(visType.schemas.buckets || visType.schemas.metrics @@ -71,8 +75,10 @@ class DefaultEditorController { ]; this.state = { - savedObj, + vis, optionTabs, + eventEmitter, + embeddableHandler, }; } diff --git a/src/legacy/core_plugins/vis_default_editor/public/vis_options_props.tsx b/src/legacy/core_plugins/vis_default_editor/public/vis_options_props.tsx index 2e8f20946c73a..3239e871a2465 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/vis_options_props.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/vis_options_props.tsx @@ -17,8 +17,8 @@ * under the License. */ +import { PersistedState } from 'src/plugins/visualizations/public'; import { IAggConfigs } from 'src/plugins/data/public'; -import { PersistedState } from '../../../../plugins/visualizations/public'; import { Vis } from '../../visualizations/public'; export interface VisOptionsProps { diff --git a/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx b/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx index 5bcb2961c42de..103879cb6e6df 100644 --- a/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx +++ b/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx @@ -21,11 +21,6 @@ import React from 'react'; import { render, mount } from 'enzyme'; import { MarkdownVisWrapper } from './markdown_vis_controller'; -// We need Markdown to do these tests, so mock data plugin -jest.mock('../../data/public/legacy', () => { - return {}; -}); - describe('markdown vis controller', () => { it('should set html from markdown params', () => { const vis = { diff --git a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.test.tsx b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.test.tsx index 6a466c9cd0211..7ba4fe017522d 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.test.tsx +++ b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.test.tsx @@ -20,12 +20,12 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { Vis } from 'src/legacy/core_plugins/visualizations/public'; import { MetricVisComponent, MetricVisComponentProps } from './metric_vis_component'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { npStart } from 'ui/new_platform'; import { fieldFormats } from '../../../../../plugins/data/public'; import { identity } from 'lodash'; +import { ExprVis } from '../../../visualizations/public/np_ready/public/expressions/vis'; jest.mock('ui/new_platform'); @@ -37,7 +37,7 @@ const baseVisData = { } as any; describe('MetricVisComponent', function() { - const vis: Vis = { + const vis: ExprVis = { params: { metric: { colorSchema: 'Green to Red', @@ -57,7 +57,7 @@ describe('MetricVisComponent', function() { const getComponent = (propOverrides: Partial = {} as Partial) => { const props: Props = { vis, - visParams: vis.params, + visParams: vis.params as any, visData: baseVisData, renderComplete: jest.fn(), ...propOverrides, diff --git a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.tsx b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.tsx index a93bb618da31f..175458497a05e 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.tsx +++ b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.tsx @@ -27,12 +27,13 @@ import { FieldFormatsContentType, IFieldFormat } from '../../../../../plugins/da import { KibanaDatatable } from '../../../../../plugins/expressions/public'; import { getHeatmapColors } from '../../../../../plugins/charts/public'; import { VisParams, MetricVisMetric } from '../types'; -import { SchemaConfig, Vis } from '../../../visualizations/public'; +import { SchemaConfig } from '../../../visualizations/public'; +import { ExprVis } from '../../../visualizations/public/np_ready/public/expressions/vis'; export interface MetricVisComponentProps { visParams: VisParams; visData: Input; - vis: Vis; + vis: ExprVis; renderComplete: () => void; } diff --git a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts index cce5864aa50a1..c0bfa47bff502 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts +++ b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts @@ -61,11 +61,22 @@ describe('metric_vis - createMetricVisTypeDefinition', () => { labelTemplate: 'ip[{{value}}]', }); + const searchSource = { + getField: (name: string) => { + if (name === 'index') { + return stubIndexPattern; + } + }, + }; + // TODO: remove when Vis is converted to typescript. Only importing Vis as type // @ts-ignore - vis = visualizationsStart.createVis(stubIndexPattern, { + vis = visualizationsStart.createVis('metric', { type: 'metric', - aggs: [{ id: '1', type: 'top_hits', schema: 'metric', params: { field: 'ip' } }], + data: { + searchSource, + aggs: [{ id: '1', type: 'top_hits', schema: 'metric', params: { field: 'ip' } }], + }, }); vis.params.dimensions = { diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js index 8edef2ea16353..211b79e915038 100644 --- a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js +++ b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js @@ -50,57 +50,73 @@ describe('Table Vis - AggTable Directive', function() { const tabifiedData = {}; const init = () => { - const vis1 = visualizationsStart.createVis(indexPattern, 'table'); - tabifiedData.metricOnly = tabifyAggResponse(vis1.aggs, metricOnly); + const searchSource = { + getField: name => { + if (name === 'index') { + return indexPattern; + } + }, + }; + const vis1 = visualizationsStart.createVis('table', { + type: 'table', + data: { searchSource, aggs: [] }, + }); + tabifiedData.metricOnly = tabifyAggResponse(vis1.data.aggs, metricOnly); - const vis2 = visualizationsStart.createVis(indexPattern, { + const vis2 = visualizationsStart.createVis('table', { type: 'table', params: { showMetricsAtAllLevels: true, }, - aggs: [ - { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, - { type: 'terms', schema: 'bucket', params: { field: 'extension' } }, - { type: 'terms', schema: 'bucket', params: { field: 'geo.src' } }, - { type: 'terms', schema: 'bucket', params: { field: 'machine.os' } }, - ], + data: { + aggs: [ + { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, + { type: 'terms', schema: 'bucket', params: { field: 'extension' } }, + { type: 'terms', schema: 'bucket', params: { field: 'geo.src' } }, + { type: 'terms', schema: 'bucket', params: { field: 'machine.os' } }, + ], + searchSource, + }, }); - vis2.aggs.aggs.forEach(function(agg, i) { + vis2.data.aggs.aggs.forEach(function(agg, i) { agg.id = 'agg_' + (i + 1); }); - tabifiedData.threeTermBuckets = tabifyAggResponse(vis2.aggs, threeTermBuckets, { + tabifiedData.threeTermBuckets = tabifyAggResponse(vis2.data.aggs, threeTermBuckets, { metricsAtAllLevels: true, }); - const vis3 = visualizationsStart.createVis(indexPattern, { + const vis3 = visualizationsStart.createVis('table', { type: 'table', - aggs: [ - { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, - { type: 'min', schema: 'metric', params: { field: '@timestamp' } }, - { type: 'terms', schema: 'bucket', params: { field: 'extension' } }, - { - type: 'date_histogram', - schema: 'bucket', - params: { field: '@timestamp', interval: 'd' }, - }, - { - type: 'derivative', - schema: 'metric', - params: { metricAgg: 'custom', customMetric: { id: '5-orderAgg', type: 'count' } }, - }, - { - type: 'top_hits', - schema: 'metric', - params: { field: 'bytes', aggregate: { val: 'min' }, size: 1 }, - }, - ], + data: { + aggs: [ + { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, + { type: 'min', schema: 'metric', params: { field: '@timestamp' } }, + { type: 'terms', schema: 'bucket', params: { field: 'extension' } }, + { + type: 'date_histogram', + schema: 'bucket', + params: { field: '@timestamp', interval: 'd' }, + }, + { + type: 'derivative', + schema: 'metric', + params: { metricAgg: 'custom', customMetric: { id: '5-orderAgg', type: 'count' } }, + }, + { + type: 'top_hits', + schema: 'metric', + params: { field: 'bytes', aggregate: { val: 'min' }, size: 1 }, + }, + ], + searchSource, + }, }); - vis3.aggs.aggs.forEach(function(agg, i) { + vis3.data.aggs.aggs.forEach(function(agg, i) { agg.id = 'agg_' + (i + 1); }); tabifiedData.oneTermOneHistogramBucketWithTwoMetricsOneTopHitOneDerivative = tabifyAggResponse( - vis3.aggs, + vis3.data.aggs, oneTermOneHistogramBucketWithTwoMetricsOneTopHitOneDerivative ); }; diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js index 89900d2144030..77f817e44ba79 100644 --- a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js +++ b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js @@ -38,22 +38,35 @@ describe('Table Vis - AggTableGroup Directive', function() { const tabifiedData = {}; const init = () => { - const vis1 = visualizationsStart.createVis(indexPattern, 'table'); - tabifiedData.metricOnly = tabifyAggResponse(vis1.aggs, metricOnly); + const searchSource = { + getField: name => { + if (name === 'index') { + return indexPattern; + } + }, + }; + const vis1 = visualizationsStart.createVis('table', { + type: 'table', + data: { searchSource, aggs: [] }, + }); + tabifiedData.metricOnly = tabifyAggResponse(vis1.data.aggs, metricOnly); - const vis2 = visualizationsStart.createVis(indexPattern, { + const vis2 = visualizationsStart.createVis('pie', { type: 'pie', - aggs: [ - { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, - { type: 'terms', schema: 'split', params: { field: 'extension' } }, - { type: 'terms', schema: 'segment', params: { field: 'geo.src' } }, - { type: 'terms', schema: 'segment', params: { field: 'machine.os' } }, - ], + data: { + aggs: [ + { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, + { type: 'terms', schema: 'split', params: { field: 'extension' } }, + { type: 'terms', schema: 'segment', params: { field: 'geo.src' } }, + { type: 'terms', schema: 'segment', params: { field: 'machine.os' } }, + ], + searchSource, + }, }); - vis2.aggs.aggs.forEach(function(agg, i) { + vis2.data.aggs.aggs.forEach(function(agg, i) { agg.id = 'agg_' + (i + 1); }); - tabifiedData.threeTermBuckets = tabifyAggResponse(vis2.aggs, threeTermBuckets); + tabifiedData.threeTermBuckets = tabifyAggResponse(vis2.data.aggs, threeTermBuckets); }; const initLocalAngular = () => { diff --git a/src/legacy/core_plugins/vis_type_table/public/table_vis_controller.test.ts b/src/legacy/core_plugins/vis_type_table/public/table_vis_controller.test.ts index 327a47093f535..ad56607e9296c 100644 --- a/src/legacy/core_plugins/vis_type_table/public/table_vis_controller.test.ts +++ b/src/legacy/core_plugins/vis_type_table/public/table_vis_controller.test.ts @@ -118,20 +118,22 @@ describe('Table Vis - Controller', () => { return ({ type: tableVisTypeDefinition, params: Object.assign({}, tableVisTypeDefinition.visConfig.defaults, params), - aggs: createAggConfigs(stubIndexPattern, [ - { type: 'count', schema: 'metric' }, - { - type: 'range', - schema: 'bucket', - params: { - field: 'bytes', - ranges: [ - { from: 0, to: 1000 }, - { from: 1000, to: 2000 }, - ], + data: { + aggs: createAggConfigs(stubIndexPattern, [ + { type: 'count', schema: 'metric' }, + { + type: 'range', + schema: 'bucket', + params: { + field: 'bytes', + ranges: [ + { from: 0, to: 1000 }, + { from: 1000, to: 2000 }, + ], + }, }, - }, - ]), + ]), + }, } as unknown) as Vis; } @@ -151,11 +153,11 @@ describe('Table Vis - Controller', () => { // basically a parameterized beforeEach function initController(vis: Vis) { - vis.aggs.aggs.forEach((agg: IAggConfig, i: number) => { + vis.data.aggs!.aggs.forEach((agg: IAggConfig, i: number) => { agg.id = 'agg_' + (i + 1); }); - tabifiedResponse = tabifyAggResponse(vis.aggs, oneRangeBucket); + tabifiedResponse = tabifyAggResponse(vis.data.aggs!, oneRangeBucket); $rootScope.vis = vis; $rootScope.visParams = vis.params; $rootScope.uiState = { diff --git a/src/legacy/core_plugins/vis_type_table/public/vis_controller.ts b/src/legacy/core_plugins/vis_type_table/public/vis_controller.ts index 2d27a99bdd8af..2feaad9f4e6b6 100644 --- a/src/legacy/core_plugins/vis_type_table/public/vis_controller.ts +++ b/src/legacy/core_plugins/vis_type_table/public/vis_controller.ts @@ -19,12 +19,12 @@ import angular, { IModule, auto, IRootScopeService, IScope, ICompileService } from 'angular'; import $ from 'jquery'; -import { isEqual } from 'lodash'; -import { Vis, VisParams } from '../../visualizations/public'; +import { VisParams } from '../../visualizations/public'; import { npStart } from './legacy_imports'; import { getAngularModule } from './get_inner_angular'; import { initTableVisLegacyModule } from './table_vis_legacy_module'; +import { ExprVis } from '../../visualizations/public/np_ready/public/expressions/vis'; const innerAngularName = 'kibana/table_vis'; @@ -32,12 +32,12 @@ export class TableVisualizationController { private tableVisModule: IModule | undefined; private injector: auto.IInjectorService | undefined; el: JQuery; - vis: Vis; + vis: ExprVis; $rootScope: IRootScopeService | null = null; $scope: (IScope & { [key: string]: any }) | undefined; $compile: ICompileService | undefined; - constructor(domeElement: Element, vis: Vis) { + constructor(domeElement: Element, vis: ExprVis) { this.el = $(domeElement); this.vis = vis; } @@ -60,7 +60,7 @@ export class TableVisualizationController { } } - async render(esResponse: object, visParams: VisParams, status: { [key: string]: boolean }) { + async render(esResponse: object, visParams: VisParams) { this.initLocalAngular(); return new Promise(async (resolve, reject) => { @@ -77,15 +77,10 @@ export class TableVisualizationController { this.$scope.visState = { params: visParams }; this.$scope.esResponse = esResponse; - if (!isEqual(this.$scope.visParams, visParams)) { - this.vis.emit('updateEditorStateParams', visParams); - } - this.$scope.visParams = visParams; this.$scope.renderComplete = resolve; this.$scope.renderFailed = reject; this.$scope.resize = Date.now(); - this.$scope.updateStatus = status; this.$scope.$apply(); }; @@ -93,7 +88,7 @@ export class TableVisualizationController { this.$scope = this.$rootScope.$new(); this.$scope.uiState = this.vis.getUiState(); updateScope(); - this.el.find('div').append(this.$compile(this.vis.type.visConfig.template)(this.$scope)); + this.el.find('div').append(this.$compile(this.vis.type!.visConfig.template)(this.$scope)); this.$scope.$apply(); } else { updateScope(); diff --git a/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js b/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js index 3091b3340cd6d..6f54744a2f508 100644 --- a/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js +++ b/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js @@ -19,7 +19,6 @@ import expect from '@kbn/expect'; import ngMock from 'ng_mock'; -import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern'; import { start as visualizationsStart } from '../../../../../core_plugins/visualizations/public/np_ready/public/legacy'; import { ImageComparator } from 'test_utils/image_comparator'; import { createTagCloudVisualization } from '../tag_cloud_visualization'; @@ -36,7 +35,6 @@ const PIXEL_DIFF = 64; describe('TagCloudVisualizationTest', function() { let domNode; - let indexPattern; let vis; let imageComparator; @@ -66,22 +64,18 @@ describe('TagCloudVisualizationTest', function() { }); beforeEach(ngMock.module('kibana')); - beforeEach( - ngMock.inject(Private => { - indexPattern = Private(LogstashIndexPatternStubProvider); - }) - ); describe('TagCloudVisualization - basics', function() { beforeEach(async function() { setupDOM('512px', '512px'); imageComparator = new ImageComparator(); - vis = visualizationsStart.createVis(indexPattern, { + vis = visualizationsStart.createVis('tagcloud', { type: 'tagcloud', params: { bucket: { accessor: 0, format: {} }, metric: { accessor: 0, format: {} }, }, + data: {}, }); }); diff --git a/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_visualization.js b/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_visualization.js index 114643c9a74e0..04f447bf78d50 100644 --- a/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_visualization.js +++ b/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_visualization.js @@ -79,17 +79,10 @@ export function createTagCloudVisualization({ colors }) { render(