diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 790abde0bd8c89..5f891bb1d0bbd2 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -13,6 +13,7 @@ /src/legacy/core_plugins/kibana/public/dev_tools/ @elastic/kibana-app /src/legacy/core_plugins/vis_type_vislib/ @elastic/kibana-app /src/plugins/vis_type_xy/ @elastic/kibana-app +/src/plugins/vis_type_table/ @elastic/kibana-app /src/plugins/kibana_legacy/ @elastic/kibana-app /src/plugins/vis_type_timelion/ @elastic/kibana-app /src/plugins/dashboard/ @elastic/kibana-app diff --git a/.i18nrc.json b/.i18nrc.json index 4a516f23ebf05d..d4286a7bd50e0f 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -48,7 +48,7 @@ "visDefaultEditor": "src/plugins/vis_default_editor", "visTypeMarkdown": "src/plugins/vis_type_markdown", "visTypeMetric": "src/plugins/vis_type_metric", - "visTypeTable": "src/legacy/core_plugins/vis_type_table", + "visTypeTable": "src/plugins/vis_type_table", "visTypeTagCloud": "src/legacy/core_plugins/vis_type_tagcloud", "visTypeTimeseries": ["src/legacy/core_plugins/vis_type_timeseries", "src/plugins/vis_type_timeseries"], "visTypeVega": "src/legacy/core_plugins/vis_type_vega", diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5c745f1611cce9..e4a9d87bc56fcc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,6 +22,7 @@ A high level overview of our contributing guidelines. - [Setting Up SSL](#setting-up-ssl) - [Linting](#linting) - [Internationalization](#internationalization) + - [Localization](#localization) - [Testing and Building](#testing-and-building) - [Debugging server code](#debugging-server-code) - [Instrumenting with Elastic APM](#instrumenting-with-elastic-apm) @@ -408,6 +409,11 @@ ReactDOM.render( There are a number of tools created to support internationalization in Kibana that would allow one to validate internationalized labels, extract them to a `JSON` file or integrate translations back to Kibana. To know more, please read corresponding [readme](src/dev/i18n/README.md) file. +### Localization + +We cannot support accepting contributions to the translations from any source other than the translators we have engaged to do the work. +We are still to develop a proper process to accept any contributed translations. We certainly appreciate that people care enough about the localization effort to want to help improve the quality. We aim to build out a more comprehensive localization process for the future and will notify you once contributions can be supported, but for the time being, we are not able to incorporate suggestions. + ### Testing and Building To ensure that your changes will not break other functionality, please run the test suite and build process before submitting your Pull Request. diff --git a/docs/images/vega_lite_default.png b/docs/images/vega_lite_default.png new file mode 100644 index 00000000000000..1ce1592d0738c6 Binary files /dev/null and b/docs/images/vega_lite_default.png differ diff --git a/docs/setup/production.asciidoc b/docs/setup/production.asciidoc index eef2b11e53d85f..19f9d64d13623d 100644 --- a/docs/setup/production.asciidoc +++ b/docs/setup/production.asciidoc @@ -133,7 +133,8 @@ server.port Settings that must be the same: -------- xpack.security.encryptionKey //decrypting session cookies -xpack.reporting.encryptionKey //decrypting reports stored in Elasticsearch +xpack.reporting.encryptionKey //decrypting reports +xpack.encryptedSavedObjects.encryptionKey // decrypting saved objects -------- Separate configuration files can be used from the command line by using the `-c` flag: diff --git a/docs/user/alerting/action-types/pagerduty.asciidoc b/docs/user/alerting/action-types/pagerduty.asciidoc index 50a1f31e4a9ae1..da34c6e0855d76 100644 --- a/docs/user/alerting/action-types/pagerduty.asciidoc +++ b/docs/user/alerting/action-types/pagerduty.asciidoc @@ -4,19 +4,142 @@ The PagerDuty action type uses the https://v2.developer.pagerduty.com/docs/events-api-v2[v2 Events API] to trigger, acknowledge, and resolve PagerDuty alerts. +* <> +* <> +* <> + +[float] +[[pagerduty-benefits]] +=== PagerDuty + Elastic integration benefits + +By integrating PagerDuty with alerts, you can: + +* Route your alerts to the right PagerDuty responder within your team, based on your structure, escalation policies, and workflows. +* Automatically generate incidents of different types and severity based on each alert’s context. +* Tailor the incident data to match your needs by easily passing the alerting context from Kibana to PagerDuty. + +[float] +[[pagerduty-how-it-works]] +==== How it works + +{kib} allows you to create alerts to notify you of a significant move +in your dataset. +You can create alerts for all your Observability, Security, and Elastic Stack use cases. +Alerts will trigger a new incident on the corresponding PagerDuty service. + +[float] +==== Requirements + +In the `kibana.yml` configuration file, you must add the <>. +This is required to encrypt parameters that must be secured, for example PagerDuty’s integration key. + +If you have security enabled: + +* You must have +application privileges to access Metrics, APM, Uptime, or SIEM. +* If you are using a self-managed deployment with security, you must have +Transport Security Layer (TLS) enabled for communication <>. +Alerts uses API keys to secure background alert checks and actions, +and API keys require {ref}/configuring-tls.html#tls-http[TLS on the HTTP interface]. + +Although not a requirement, to harden the integrations security you might want to +review the <> that are available to you. + +[float] +[[pagerduty-support]] +==== Support +If you need help with this integration, get in touch with the {kib} team by visiting +https://support.elastic.co[support.elastic.co] or by using the *Ask Elastic* option in the {kib} Help menu. +You can also select the {kib} category at https://discuss.elastic.co/[discuss.elastic.co]. + +[float] +[[pagerduty-integration-walkthrough]] +==== Integration with PagerDuty walkthrough + +[float] +[[pagerduty-in-pagerduty]] +===== In PagerDuty + +. From the *Configuration* menu, select *Services*. +. Add an integration to a service: ++ +* If you are adding your integration to an existing service, +click the name of the service you want to add the integration to. +Then, select the *Integrations* tab and click the *New Integration* button. +* If you are creating a new service for your integration, +go to +https://support.pagerduty.com/docs/services-and-integrations#section-configuring-services-and-integrations[Configuring Services and Integrations] +and follow the steps outlined in the *Create a New Service* section, selecting *Elastic* as the *Integration Type* in step 4. +Continue with the <> section once you have finished these steps. + +. Enter an *Integration Name* in the format Elastic-service-name (for example, Elastic-Alerting or Kibana-APM-Alerting) +and select Elastic from the *Integration Type* menu. +. Click *Add Integration* to save your new integration. ++ +You will be redirected to the *Integrations* tab for your service. An Integration Key is generated on this screen. ++ +[role="screenshot"] +image::user/alerting/images/pagerduty-integration.png[PagerDuty Integrations tab] + +. Save this key, as you will use it when you configure the integration with Elastic in the next section. + +[float] +[[pagerduty-in-elastic]] +===== In Elastic + +. Create a PagerDuty Connector in Kibana. You can: ++ +* Create a connector as part of creating an alert by selecting PagerDuty in the *Actions* +section of the alert configuration and selecting *Add new*. +* Alternatively, create a connector by navigating to *Management* from the {kib} navbar and selecting +*Alerts and Actions*. Then, select the *Connectors* tab, click the *Create connector* button, and select the PagerDuty option. + +. Configure the connector by giving it a name and optionally entering the API URL and Routing Key, or using the defaults. ++ +See <> for how to obtain the endpoint and key information from PagerDuty and +<> for more details. + +. Save the Connector. + +. Create an alert using *Management > Alerts and Actions* or the application of your choice. + +. Set up an action using your PagerDuty connector, by determining: ++ +* The action’s type: Trigger, Resolve, or Acknowledge. +* The event’s severity: Info, warning, error, or critical. +* An array of different fields, including the timestamp, group, class, component, and your dedup key. +Depending on your custom needs, assign them variables from the alerting context. +To see the available context variables, click on the *Add alert variable* icon next +to each corresponding field. For more details on these parameters, see the +<> and the PagerDuty +https://v2.developer.pagerduty.com/v2/docs/send-an-event-events-api-v2[API v2 documentation]. + + +[float] +[[pagerduty-uninstall]] +==== How to uninstall +To remove a PagerDuty connector from an alert, simply remove it +from the *Actions* section of that alert, using the remove (x) icon. +This will disable the integration for the particular alert. + +To delete the connector entirely, go to *Management > Alerts and Actions*. +Select the *Connectors* tab, and then click on the delete icon. +This is an irreversible action and impacts all alerts that use this connector. + + [float] [[pagerduty-connector-configuration]] -==== Connector configuration +=== Connector configuration PagerDuty connectors have the following configuration properties: Name:: The name of the connector. The name is used to identify a connector in the management UI connector listing, or in the connector list when configuring an action. -API URL:: An optional PagerDuty event URL. Defaults to `https://events.pagerduty.com/v2/enqueue`. If you are using the <> setting, make sure the hostname is whitelisted. +API URL:: An optional PagerDuty event URL. Defaults to `https://events.pagerduty.com/v2/enqueue`. If you are using the <> setting, make sure the hostname is whitelisted. Routing Key:: A 32 character PagerDuty Integration Key for an integration on a service or on a global ruleset. [float] [[pagerduty-action-configuration]] -==== Action configuration +=== Action configuration PagerDuty actions have the following properties: @@ -26,8 +149,8 @@ Dedup Key:: All actions sharing this key will be associated with the same Pa Timestamp:: An *optional* https://v2.developer.pagerduty.com/v2/docs/types#datetime[ISO-8601 format date-time], indicating the time the event was detected or generated. Component:: An *optional* value indicating the component of the source machine that is responsible for the event, for example `mysql` or `eth0`. Group:: An *optional* value indicating the logical grouping of components of a service, for example `app-stack`. -Source:: An *optional* value indicating the affected system, preferably a hostname or fully qualified domain name. Defaults to the {kib} saved object id of the action. +Source:: An *optional* value indicating the affected system, preferably a hostname or fully qualified domain name. Defaults to the {kib} saved object id of the action. Summary:: An *optional* text summary of the event, defaults to `No summary provided`. The maximum length is 1024 characters. Class:: An *optional* value indicating the class/type of the event, for example `ping failure` or `cpu load`. -For more details on these properties, see https://v2.developer.pagerduty.com/v2/docs/send-an-event-events-api-v2[PagerDuty v2 event parameters]. \ No newline at end of file +For more details on these properties, see https://v2.developer.pagerduty.com/v2/docs/send-an-event-events-api-v2[PagerDuty v2 event parameters]. diff --git a/docs/user/alerting/images/pagerduty-integration.png b/docs/user/alerting/images/pagerduty-integration.png new file mode 100755 index 00000000000000..0a270de866b36e Binary files /dev/null and b/docs/user/alerting/images/pagerduty-integration.png differ diff --git a/docs/visualize/vega.asciidoc b/docs/visualize/vega.asciidoc index b8c0d1dbe3ddaf..e0d9955f0c3dbf 100644 --- a/docs/visualize/vega.asciidoc +++ b/docs/visualize/vega.asciidoc @@ -1,81 +1,80 @@ [[vega-graph]] -== Vega Graphs -experimental[] +== Vega -You can build https://vega.github.io/vega/examples/[Vega] and -https://vega.github.io/vega-lite/examples/[Vega-Lite] data visualizations -into Kibana, either standalone, or on top of a map. To see Vega in action, -watch this -https://www.youtube.com/watch?v=lQGCipY3th8[short introduction video]. +experimental[] -Currently Vega version 4.3 and Vega-Lite version 2.6 are supported. +Build custom visualizations from multiple data sources using Vega +and Vega-Lite. -NOTE: In Vega it is possible to load data dynamically, e.g. by setting signals as data urls. This is not supported in Kibana as all data is fetched at once prior to passing it to the Vega renderer. +* *Vega* — A declarative format to create visualizations using JSON. + Generate interactive displays using D3. +* *Vega-Lite* — An easier format to use than Vega that enables more rapid + data analysis. Compiles into Vega. -[[vega-quick-demo]] -=== Getting Started with Vega +For more information about Vega and Vega-Lite, refer to +<>. -* To experiment using sample data, first click the {kib} logo in the upper left hand corner -and then click the link next to *Sample Data*. -* Once you have data loaded, go to *Visualize*, click *+*, and select *Vega* to see an example graph. -*Note*: The default graph is written in Vega-Lite, but you can build visualizations -in either language. See <> for more information. -* Try changing `mark` from `line` to `point`, `area`, `bar`, `circle`, -or `square`. Check out the -https://vega.github.io/vega-lite/docs/mark.html#mark-def[Vega-Lite docs] for more information. -* Explore other available https://vega.github.io/vega/examples/[Vega] or -https://vega.github.io/vega-lite/examples/[Vega-Lite] visualizations. -*Note*: You might need to make URLs absolute, for example, replace -`"url": "data/world-110m.json"` with -`"url": "https://vega.github.io/editor/data/world-110m.json"`. -See <>. -* For more information on getting started, check out this https://www.elastic.co/blog/getting-started-with-vega-visualizations-in-kibana[blog post]. +[float] +[[create-vega-viz]] +=== Create Vega visualizations +You create Vega visualizations by using the text editor, which is +preconfigured with the options you need. -[[vega-vs-vegalite]] -=== Vega vs Vega-Lite +[role="screenshot"] +image::images/vega_lite_default.png[] -The Vega visualization in {kib} supports both Vega and Vega-Lite. You can use the -`schema` value to define which language you would like to use and its minimum -required version. +[float] +[[vega-schema]] +==== Change the Vega version -For example: +The default visualization uses Vega-Lite version 2. To use Vega version 4, edit +the `schema`. -* Vega-Lite v2: `$schema: https://vega.github.io/schema/vega-lite/v2.json` -* Vega v4: `$schema: https://vega.github.io/schema/vega/v4.json` +Go to `$schema`, enter `https://vega.github.io/schema/vega/v4.json`, then click +*Update*. -The `schema` URL is only used for identification, and does not need to be accessible by {kib}. +[float] +[[vega-type]] +==== Change the visualization type -Vega-Lite is a simplified version of Vega; it automates some constructions and has -much shorter specifications than Vega. Vega-Lite is automatically converted into -Vega before rendering, but it has some limitations, and there are some visualizations -that can be expressed in Vega that cannot be expressed in Vega-Lite. You can learn more -in the https://vega.github.io/vega-lite/[Vega-Lite documentation]. +The default visualization is a line chart. To change the visualization type, +change the `mark` value. The supported visualization types are listed in the +text editor. -You can use https://vega.github.io/editor/[this editor] to convert Vega-Lite into -Vega. +Go to `mark`, change the value to a different visualization type, then click +*Update*. -When you create a Vega visualization in {kib}, you can edit the `schema` -value in the dev tools to the left of the graph to define which of the two expression -languages you would like to use. +[float] +[[vega-sizing-and-positioning]] +==== Change the layout +By default, Vega visualizations use the `autosize = { type: 'fit', contains: 'padding' }` layout. +`fit` uses all available space, ignores `width` and `height` values, +and respects the padding values. To override this behavior, change the +`autosize` value. [[vega-querying-elasticsearch]] -=== Querying Elasticsearch +=== Query {es} -By default, Vega's https://vega.github.io/vega/docs/data/[data] element -can use embedded and external data with a `"url"` parameter. Kibana adds support for the direct Elasticsearch queries by overloading +experimental[] Vega https://vega.github.io/vega/docs/data/[data] elements +use embedded and external data with a `"url"` parameter. {kib} adds support for +direct {es} queries by overloading the `"url"` value. -Here is an example of an Elasticsearch query that counts the number of documents in all indexes. The query uses *@timestamp* field to filter the time range, and break it into histogram buckets. +NOTE: With Vega, you dynamically load your data by setting signals as data URLs. +Since {kib} is unable to support dynamically loaded data, all data is fetched +before it's passed to the Vega renderer. + +For example, count the number of documents in all indices: [source,yaml] ---- -// An object instead of a string for the url value +// An object instead of a string for the URL value // is treated as a context-aware Elasticsearch query. url: { - // Specify the time filter (upper right corner) with this field + // Specify the time filter. %timefield%: @timestamp // Apply dashboard context filters when set %context%: true @@ -88,8 +87,8 @@ url: { time_buckets: { date_histogram: { // Use date histogram aggregation on @timestamp field - field: @timestamp - // interval value will depend on the daterange picker + field: @timestamp <1> + // interval value will depend on the time filter // Use an integer to set approximate bucket count interval: { %autointerval%: true } // Make sure we get an entire range, even if it has no data @@ -109,7 +108,10 @@ url: { } ---- -The full result has this kind of structure: +<1> `@timestamp` — Filters the time range and breaks it into histogram +buckets. + +The full result includes the following structure: [source,yaml] ---- @@ -118,23 +120,24 @@ The full result has this kind of structure: "time_buckets": { "buckets": [{ "key_as_string": "2015-11-30T22:00:00.000Z", - "key": 1448920800000, + "key": 1448920800000,<1> "doc_count": 28 }, { "key_as_string": "2015-11-30T23:00:00.000Z", - "key": 1448924400000, + "key": 1448924400000, <1> "doc_count": 330 }, ... ---- -Note that `"key"` is a unix timestamp, and can be used without conversions by the +<1> `"key"` — The unix timestamp you can use without conversions by the Vega date expressions. -For most graphs we only need the list of the bucket values, so we use `format: {property: "aggregations.time_buckets.buckets"}` expression to focus on just the data we need. +For most visualizations, you only need the list of bucket values. To focus on +only the data you need, use `format: {property: "aggregations.time_buckets.buckets"}`. -Query may be specified with individual range and dashboard context as -well. This query is equivalent to `"%context%": true, "%timefield%": "@timestamp"`, -except that the timerange is shifted back by 10 minutes: +Specify a query with individual range and dashboard context. The query is +equivalent to `"%context%": true, "%timefield%": "@timestamp"`, +except that the time range is shifted back by 10 minutes: [source,yaml] ---- @@ -185,9 +188,9 @@ on the currently picked range: `"interval": {"%autointerval%": 10}` will try to get about 10-15 data points (buckets). [[vega-esmfiles]] -=== Elastic Map Files +=== Access Elastic Map Service files -It is possible to access Elastic Map Service's files via the same mechanism +experimental[] Access the Elastic Map Service files via the same mechanism: [source,yaml] ---- @@ -203,11 +206,8 @@ url: { format: {property: "features"} ---- -[[vega-with-a-map]] -=== Vega with a Map - -Kibana's default map can be used as a base of the Vega graph. To enable, -the graph must specify `type=map` in the host configuration: +To enable Elastic Maps, the graph must specify `type=map` in the host +configuration: [source,yaml] ---- @@ -247,42 +247,47 @@ the graph must specify `type=map` in the host configuration: } ---- -This visualization will automatically inject a projection called -`"projection"`. Use it to calculate positioning of all geo-aware marks. -Additionally, you may use `latitude`, `longitude`, and `zoom` signals. +The visualization automatically injects a `"projection"`, which you can use to +calculate the position of all geo-aware marks. +Additionally, you can use `latitude`, `longitude`, and `zoom` signals. These signals can be used in the graph, or can be updated to modify the -positioning of the map. +position of the map. + +Vega visualization ignore the `autosize`, `width`, `height`, and `padding` +values, using `fit` model with zero padding. [[vega-debugging]] -=== Debugging +=== Debugging Vega [[vega-browser-debugging-console]] -==== Browser Debugging console +==== Browser debugging console -Use browser debugging tools (e.g. F12 or Ctrl+Shift+J in Chrome) to +experimental[] Use browser debugging tools (for example, F12 or Ctrl+Shift+J in Chrome) to inspect the `VEGA_DEBUG` variable: -* `view` - access to the Vega View object. See https://vega.github.io/vega/docs/api/debugging/[Vega Debugging Guide] - on how to inspect data and signals at runtime. For Vega-Lite, `VEGA_DEBUG.view.data('source_0')` gets the main data set. - For Vega, it uses the data name as defined in your Vega spec. -* `vega_spec` - Vega JSON graph specification after some modifications by Kibana. In case ++ +* `view` — Access to the Vega View object. See https://vega.github.io/vega/docs/api/debugging/[Vega Debugging Guide] +on how to inspect data and signals at runtime. For Vega-Lite, `VEGA_DEBUG.view.data('source_0')` gets the main data set. +For Vega, it uses the data name as defined in your Vega spec. + +* `vega_spec` — Vega JSON graph specification after some modifications by {kib}. In case of Vega-Lite, this is the output of the Vega-Lite compiler. -* `vegalite_spec` - If this is a Vega-Lite graph, JSON specification of the graph before + +* `vegalite_spec` — If this is a Vega-Lite graph, JSON specification of the graph before Vega-Lite compilation. [[vega-data]] ==== Data -If you are using Elasticsearch query, make sure your resulting data is -what you expected. The easiest way to view it is by using "networking" -tab in the browser debugging tools (e.g. F12). Modify the graph slightly +experimental[] If you are using an {es} query, make sure your resulting data is +what you expected. The easiest way to view it is by using the "networking" +tab in the browser debugging tools (for example, F12). Modify the graph slightly so that it makes a search request, and view the response from the server. Another approach is to use -https://www.elastic.co/guide/en/kibana/current/console-kibana.html[Kibana -Dev Tools] tab - place the index name into the first line: -`GET /_search`, and add your query as the following lines -(just the value of the `"query"` field) +https://www.elastic.co/guide/en/kibana/current/console-kibana.html[Dev Tools]. Place the index name into the first line: +`GET /_search`, then add your query as the following lines +(just the value of the `"query"` field). -If you need to share your graph with someone, you may want to copy the +If you need to share your graph with someone, copy the raw data response to https://gist.github.com/[gist.github.com], possibly with a `.json` extension, use the `[raw]` button, and use that url directly in your graph. @@ -292,9 +297,11 @@ to your kibana.yml file. [[vega-notes]] [[vega-useful-links]] -=== Useful Links +=== Resources and examples + +experimental[] To learn more about Vega and Vega-List, refer to the resources and examples. -==== Vega Editor +==== Vega editor The https://vega.github.io/editor/[Vega Editor] includes examples for Vega & Vega-Lite, but does not support any {kib}-specific features like {es} requests and interactive base maps. @@ -308,28 +315,15 @@ The https://vega.github.io/editor/[Vega Editor] includes examples for Vega & Veg * https://vega.github.io/vega/docs/[Docs] * https://vega.github.io/vega/examples/[Examples] -==== Elastic blog posts -* https://www.elastic.co/blog/getting-started-with-vega-visualizations-in-kibana[Getting Started with Vega Visualizations in Kibana] -* https://www.elastic.co/blog/custom-vega-visualizations-in-kibana[Custom Vega Visualizations in Kibana] -* https://www.elastic.co/blog/sankey-visualization-with-vega-in-kibana[Sankey Visualization with Vega in Kibana] - - -[[vega-using-vega-and-vegalite-examples]] -==== Using Vega and Vega-Lite examples - -When using https://vega.github.io/vega/examples/[Vega] and -https://vega.github.io/vega-lite/examples/[VegaLite] examples, you may +TIP: When you use the examples, you may need to modify the "data" section to use absolute URL. For example, replace `"url": "data/world-110m.json"` with -`"url": "https://vega.github.io/editor/data/world-110m.json"`. Also, -regular Vega examples use `"autosize": "pad"` layout model, whereas -Kibana uses `fit`. Remove all `autosize`, `width`, and `height` -values. See link:#sizing-and-positioning[sizing and positioning]. +`"url": "https://vega.github.io/editor/data/world-110m.json"`. [[vega-additional-configuration-options]] ==== Additional configuration options -These options are specific to the Kibana. link:#vega-with-a-map[Map support] has +These options are specific to the {kib}. link:#vega-with-a-map[Map support] has additional configuration options. [source,yaml] @@ -351,21 +345,3 @@ additional configuration options. /* the rest of Vega code */ } ---- - -[[vega-sizing-and-positioning]] -==== Sizing and positioning - -[[vega-and-vegalite]] -===== Vega and Vega-Lite - -By default, Kibana Vega graphs will use -`autosize = { type: 'fit', contains: 'padding' }` layout model for Vega -and Vega-Lite graphs. The `fit` model uses all available space, ignores -`width` and `height` values, but respects the padding values. You may -override this behaviour by specifying a different `autosize` value. - -[[vega-on-a-map]] -===== Vega on a map - -All Vega graphs will ignore `autosize`, `width`, `height`, and `padding` -values, using `fit` model with zero padding. diff --git a/packages/kbn-config-schema/src/types/object_type.test.ts b/packages/kbn-config-schema/src/types/object_type.test.ts index 47a0f5f7a5491c..5ab59d1c020779 100644 --- a/packages/kbn-config-schema/src/types/object_type.test.ts +++ b/packages/kbn-config-schema/src/types/object_type.test.ts @@ -18,6 +18,7 @@ */ import { schema } from '..'; +import { TypeOf } from './object_type'; test('returns value by default', () => { const type = schema.object({ @@ -350,3 +351,26 @@ test('unknowns = `ignore` affects only own keys', () => { }) ).toThrowErrorMatchingInlineSnapshot(`"[foo.baz]: definition for this key is missing"`); }); + +test('handles optional properties', () => { + const type = schema.object({ + required: schema.string(), + optional: schema.maybe(schema.string()), + }); + + type SchemaType = TypeOf; + + let foo: SchemaType = { + required: 'foo', + }; + foo = { + required: 'hello', + optional: undefined, + }; + foo = { + required: 'hello', + optional: 'bar', + }; + + expect(foo).toBeDefined(); +}); diff --git a/packages/kbn-config-schema/src/types/object_type.ts b/packages/kbn-config-schema/src/types/object_type.ts index 5a50e714a59311..fee2d02c1bfb96 100644 --- a/packages/kbn-config-schema/src/types/object_type.ts +++ b/packages/kbn-config-schema/src/types/object_type.ts @@ -26,9 +26,26 @@ export type Props = Record>; export type TypeOf> = RT['type']; +type OptionalProperties = Pick< + Base, + { + [Key in keyof Base]: undefined extends TypeOf ? Key : never; + }[keyof Base] +>; + +type RequiredProperties = Pick< + Base, + { + [Key in keyof Base]: undefined extends TypeOf ? never : Key; + }[keyof Base] +>; + // Because of https://github.com/Microsoft/TypeScript/issues/14041 // this might not have perfect _rendering_ output, but it will be typed. -export type ObjectResultType

= Readonly<{ [K in keyof P]: TypeOf }>; +export type ObjectResultType

= Readonly< + { [K in keyof OptionalProperties

]?: TypeOf } & + { [K in keyof RequiredProperties

]: TypeOf } +>; interface UnknownOptions { /** @@ -40,9 +57,7 @@ interface UnknownOptions { unknowns?: 'allow' | 'ignore' | 'forbid'; } -export type ObjectTypeOptions

= TypeOptions< - { [K in keyof P]: TypeOf } -> & +export type ObjectTypeOptions

= TypeOptions> & UnknownOptions; export class ObjectType

extends Type> { diff --git a/packages/kbn-test/src/functional_test_runner/functional_test_runner.ts b/packages/kbn-test/src/functional_test_runner/functional_test_runner.ts index 03075dd4081fd4..3a66ba22ccf3d4 100644 --- a/packages/kbn-test/src/functional_test_runner/functional_test_runner.ts +++ b/packages/kbn-test/src/functional_test_runner/functional_test_runner.ts @@ -30,6 +30,7 @@ import { setupMocha, runTests, Config, + SuiteTracker, } from './lib'; export class FunctionalTestRunner { @@ -52,6 +53,8 @@ export class FunctionalTestRunner { async run() { return await this._run(async (config, coreProviders) => { + SuiteTracker.startTracking(this.lifecycle, this.configFile); + const providers = new ProviderCollection(this.log, [ ...coreProviders, ...readProviderSpec('Service', config.get('services')), diff --git a/packages/kbn-test/src/functional_test_runner/lib/index.ts b/packages/kbn-test/src/functional_test_runner/lib/index.ts index 8940eccad503a4..2e534974e1d76c 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/index.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/index.ts @@ -23,3 +23,4 @@ export { readConfigFile, Config } from './config'; export { readProviderSpec, ProviderCollection, Provider } from './providers'; export { runTests, setupMocha } from './mocha'; export { FailureMetadata } from './failure_metadata'; +export { SuiteTracker } from './suite_tracker'; diff --git a/packages/kbn-test/src/functional_test_runner/lib/suite_tracker.test.ts b/packages/kbn-test/src/functional_test_runner/lib/suite_tracker.test.ts new file mode 100644 index 00000000000000..b6c2c0a6d511d1 --- /dev/null +++ b/packages/kbn-test/src/functional_test_runner/lib/suite_tracker.test.ts @@ -0,0 +1,197 @@ +/* + * 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 fs from 'fs'; +import { join, resolve } from 'path'; + +jest.mock('fs'); +jest.mock('@kbn/dev-utils', () => { + return { REPO_ROOT: '/dev/null/root' }; +}); + +import { REPO_ROOT } from '@kbn/dev-utils'; +import { Lifecycle } from './lifecycle'; +import { SuiteTracker } from './suite_tracker'; + +const DEFAULT_TEST_METADATA_PATH = join(REPO_ROOT, 'target', 'test_metadata.json'); +const MOCK_CONFIG_PATH = join('test', 'config.js'); +const MOCK_TEST_PATH = join('test', 'apps', 'test.js'); +const ENVS_TO_RESET = ['TEST_METADATA_PATH']; + +describe('SuiteTracker', () => { + const originalEnvs: Record = {}; + + beforeEach(() => { + for (const env of ENVS_TO_RESET) { + if (env in process.env) { + originalEnvs[env] = process.env[env] || ''; + delete process.env[env]; + } + } + }); + + afterEach(() => { + for (const env of ENVS_TO_RESET) { + delete process.env[env]; + } + + for (const env of Object.keys(originalEnvs)) { + process.env[env] = originalEnvs[env]; + } + + jest.resetAllMocks(); + }); + + let MOCKS: Record; + + const createMock = (overrides = {}) => { + return { + file: resolve(REPO_ROOT, MOCK_TEST_PATH), + title: 'A Test', + suiteTag: MOCK_TEST_PATH, + ...overrides, + }; + }; + + const runLifecycleWithMocks = async (mocks: object[], fn: (objs: any) => any = () => {}) => { + const lifecycle = new Lifecycle(); + const suiteTracker = SuiteTracker.startTracking( + lifecycle, + resolve(REPO_ROOT, MOCK_CONFIG_PATH) + ); + + const ret = { lifecycle, suiteTracker }; + + for (const mock of mocks) { + await lifecycle.beforeTestSuite.trigger(mock); + } + + if (fn) { + fn(ret); + } + + for (const mock of mocks.reverse()) { + await lifecycle.afterTestSuite.trigger(mock); + } + + return ret; + }; + + beforeEach(() => { + MOCKS = { + WITH_TESTS: createMock({ tests: [{}] }), // i.e. a describe with tests in it + WITHOUT_TESTS: createMock(), // i.e. a describe with only other describes in it + }; + }); + + it('collects metadata for a single suite with multiple describe()s', async () => { + const { suiteTracker } = await runLifecycleWithMocks([MOCKS.WITHOUT_TESTS, MOCKS.WITH_TESTS]); + + const suites = suiteTracker.getAllFinishedSuites(); + expect(suites.length).toBe(1); + const suite = suites[0]; + + expect(suite).toMatchObject({ + config: MOCK_CONFIG_PATH, + file: MOCK_TEST_PATH, + tag: MOCK_TEST_PATH, + hasTests: true, + success: true, + }); + }); + + it('writes metadata to a file when cleanup is triggered', async () => { + const { lifecycle, suiteTracker } = await runLifecycleWithMocks([MOCKS.WITH_TESTS]); + await lifecycle.cleanup.trigger(); + + const suites = suiteTracker.getAllFinishedSuites(); + + const call = (fs.writeFileSync as jest.Mock).mock.calls[0]; + expect(call[0]).toEqual(DEFAULT_TEST_METADATA_PATH); + expect(call[1]).toEqual(JSON.stringify(suites, null, 2)); + }); + + it('respects TEST_METADATA_PATH env var for metadata target override', async () => { + process.env.TEST_METADATA_PATH = resolve(REPO_ROOT, '../fake-test-path'); + const { lifecycle } = await runLifecycleWithMocks([MOCKS.WITH_TESTS]); + await lifecycle.cleanup.trigger(); + + expect((fs.writeFileSync as jest.Mock).mock.calls[0][0]).toEqual( + process.env.TEST_METADATA_PATH + ); + }); + + it('identifies suites with tests as leaf suites', async () => { + const root = createMock({ title: 'root', file: join(REPO_ROOT, 'root.js') }); + const parent = createMock({ parent: root }); + const withTests = createMock({ parent, tests: [{}] }); + + const { suiteTracker } = await runLifecycleWithMocks([root, parent, withTests]); + const suites = suiteTracker.getAllFinishedSuites(); + + const finishedRoot = suites.find(s => s.title === 'root'); + const finishedWithTests = suites.find(s => s.title !== 'root'); + + expect(finishedRoot).toBeTruthy(); + expect(finishedRoot?.hasTests).toBeFalsy(); + expect(finishedWithTests?.hasTests).toBe(true); + }); + + describe('with a failing suite', () => { + let root: any; + let parent: any; + let failed: any; + + beforeEach(() => { + root = createMock({ file: join(REPO_ROOT, 'root.js') }); + parent = createMock({ parent: root }); + failed = createMock({ parent, tests: [{}] }); + }); + + it('marks parent suites as not successful when a test fails', async () => { + const { suiteTracker } = await runLifecycleWithMocks( + [root, parent, failed], + async ({ lifecycle }) => { + await lifecycle.testFailure.trigger(Error('test'), { parent: failed }); + } + ); + + const suites = suiteTracker.getAllFinishedSuites(); + expect(suites.length).toBe(2); + for (const suite of suites) { + expect(suite.success).toBeFalsy(); + } + }); + + it('marks parent suites as not successful when a test hook fails', async () => { + const { suiteTracker } = await runLifecycleWithMocks( + [root, parent, failed], + async ({ lifecycle }) => { + await lifecycle.testHookFailure.trigger(Error('test'), { parent: failed }); + } + ); + + const suites = suiteTracker.getAllFinishedSuites(); + expect(suites.length).toBe(2); + for (const suite of suites) { + expect(suite.success).toBeFalsy(); + } + }); + }); +}); diff --git a/packages/kbn-test/src/functional_test_runner/lib/suite_tracker.ts b/packages/kbn-test/src/functional_test_runner/lib/suite_tracker.ts new file mode 100644 index 00000000000000..8967251ea78de7 --- /dev/null +++ b/packages/kbn-test/src/functional_test_runner/lib/suite_tracker.ts @@ -0,0 +1,147 @@ +/* + * 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 fs from 'fs'; +import { dirname, relative, resolve } from 'path'; + +import { REPO_ROOT } from '@kbn/dev-utils'; + +import { Lifecycle } from './lifecycle'; + +export interface SuiteInProgress { + startTime?: Date; + endTime?: Date; + success?: boolean; +} + +export interface SuiteWithMetadata { + config: string; + file: string; + tag: string; + title: string; + startTime: Date; + endTime: Date; + duration: number; + success: boolean; + hasTests: boolean; +} + +const getTestMetadataPath = () => { + return process.env.TEST_METADATA_PATH || resolve(REPO_ROOT, 'target', 'test_metadata.json'); +}; + +export class SuiteTracker { + finishedSuitesByConfig: Record> = {}; + inProgressSuites: Map = new Map(); + + static startTracking(lifecycle: Lifecycle, configPath: string): SuiteTracker { + const suiteTracker = new SuiteTracker(lifecycle, configPath); + return suiteTracker; + } + + getTracked(suite: object): SuiteInProgress { + if (!this.inProgressSuites.has(suite)) { + this.inProgressSuites.set(suite, { success: undefined } as SuiteInProgress); + } + return this.inProgressSuites.get(suite)!; + } + + constructor(lifecycle: Lifecycle, configPathAbsolute: string) { + if (fs.existsSync(getTestMetadataPath())) { + fs.unlinkSync(getTestMetadataPath()); + } else { + fs.mkdirSync(dirname(getTestMetadataPath()), { recursive: true }); + } + + const config = relative(REPO_ROOT, configPathAbsolute); + + lifecycle.beforeTestSuite.add(suite => { + const tracked = this.getTracked(suite); + tracked.startTime = new Date(); + }); + + // If a test fails, we want to make sure all of the ancestors, all the way up to the root, get marked as failed + // This information is not available on the mocha objects without traversing all descendants of a given node + const handleFailure = (_: any, test: any) => { + let parent = test.parent; + + // Infinite loop protection, just in case + for (let i = 0; i < 500 && parent; i++) { + if (this.inProgressSuites.has(parent)) { + this.getTracked(parent).success = false; + } + parent = parent.parent; + } + }; + + lifecycle.testFailure.add(handleFailure); + lifecycle.testHookFailure.add(handleFailure); + + lifecycle.afterTestSuite.add(suite => { + const tracked = this.getTracked(suite); + tracked.endTime = new Date(); + + // The suite ended without any children failing, so we can mark it as successful + if (typeof tracked.success === 'undefined') { + tracked.success = true; + } + + let duration = tracked.endTime.getTime() - (tracked.startTime || new Date()).getTime(); + duration = Math.floor(duration / 1000); + + const file = relative(REPO_ROOT, suite.file); + + this.finishedSuitesByConfig[config] = this.finishedSuitesByConfig[config] || {}; + + // This will get called multiple times for a test file that has multiple describes in it or similar + // This is okay, because the last one that fires is always the root of the file, which is is the one we ultimately want + this.finishedSuitesByConfig[config][file] = { + ...tracked, + duration, + config, + file, + tag: suite.suiteTag, + title: suite.title, + hasTests: !!( + (suite.tests && suite.tests.length) || + // The below statement is so that `hasTests` will bubble up nested describes in the same file + (this.finishedSuitesByConfig[config][file] && + this.finishedSuitesByConfig[config][file].hasTests) + ), + } as SuiteWithMetadata; + }); + + lifecycle.cleanup.add(() => { + const suites = this.getAllFinishedSuites(); + + fs.writeFileSync(getTestMetadataPath(), JSON.stringify(suites, null, 2)); + }); + } + + getAllFinishedSuites() { + const flattened: SuiteWithMetadata[] = []; + for (const byFile of Object.values(this.finishedSuitesByConfig)) { + for (const suite of Object.values(byFile)) { + flattened.push(suite); + } + } + + flattened.sort((a, b) => b.duration - a.duration); + return flattened; + } +} diff --git a/src/core/public/plugins/plugin_loader.test.ts b/src/core/public/plugins/plugin_loader.test.ts index 18cc2d7a6f182e..b4e2c3095f14a7 100644 --- a/src/core/public/plugins/plugin_loader.test.ts +++ b/src/core/public/plugins/plugin_loader.test.ts @@ -62,7 +62,7 @@ test('`loadPluginBundles` creates a script tag and loads initializer', async () const fakeScriptTag = createdScriptTags[0]; expect(fakeScriptTag.setAttribute).toHaveBeenCalledWith( 'src', - '/bundles/plugin:plugin-a/plugin-a.plugin.js' + '/bundles/plugin/plugin-a/plugin-a.plugin.js' ); expect(fakeScriptTag.setAttribute).toHaveBeenCalledWith('id', 'kbn-plugin-plugin-a'); expect(fakeScriptTag.onload).toBeInstanceOf(Function); @@ -85,7 +85,7 @@ test('`loadPluginBundles` includes the basePath', async () => { const fakeScriptTag = createdScriptTags[0]; expect(fakeScriptTag.setAttribute).toHaveBeenCalledWith( 'src', - '/mybasepath/bundles/plugin:plugin-a/plugin-a.plugin.js' + '/mybasepath/bundles/plugin/plugin-a/plugin-a.plugin.js' ); }); @@ -96,7 +96,7 @@ test('`loadPluginBundles` rejects if script.onerror is called', async () => { fakeScriptTag1.onerror(new Error('Whoa there!')); await expect(loadPromise).rejects.toThrowErrorMatchingInlineSnapshot( - `"Failed to load \\"plugin-a\\" bundle (/bundles/plugin:plugin-a/plugin-a.plugin.js)"` + `"Failed to load \\"plugin-a\\" bundle (/bundles/plugin/plugin-a/plugin-a.plugin.js)"` ); }); @@ -105,7 +105,7 @@ test('`loadPluginBundles` rejects if timeout is reached', async () => { // Override the timeout to 1 ms for testi. loadPluginBundle(addBasePath, 'plugin-a', { timeoutMs: 1 }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Timeout reached when loading \\"plugin-a\\" bundle (/bundles/plugin:plugin-a/plugin-a.plugin.js)"` + `"Timeout reached when loading \\"plugin-a\\" bundle (/bundles/plugin/plugin-a/plugin-a.plugin.js)"` ); }); @@ -115,11 +115,11 @@ test('`loadPluginBundles` rejects if bundle does attach an initializer to window const fakeScriptTag1 = createdScriptTags[0]; // Setup a fake initializer as if a plugin bundle had actually been loaded. - coreWindow.__kbnBundles__['plugin:plugin-a'] = undefined; + coreWindow.__kbnBundles__['plugin/plugin-a'] = undefined; // Call the onload callback fakeScriptTag1.onload(); await expect(loadPromise).rejects.toThrowErrorMatchingInlineSnapshot( - `"Definition of plugin \\"plugin-a\\" should be a function (/bundles/plugin:plugin-a/plugin-a.plugin.js)."` + `"Definition of plugin \\"plugin-a\\" should be a function (/bundles/plugin/plugin-a/plugin-a.plugin.js)."` ); }); diff --git a/src/core/public/plugins/plugin_loader.ts b/src/core/public/plugins/plugin_loader.ts index 9b35588dfe7262..bf7711055e97ba 100644 --- a/src/core/public/plugins/plugin_loader.ts +++ b/src/core/public/plugins/plugin_loader.ts @@ -93,7 +93,7 @@ export const loadPluginBundle: LoadPluginBundle = < const script = document.createElement('script'); // Assumes that all plugin bundles get put into the bundles/plugins subdirectory - const bundlePath = addBasePath(`/bundles/plugin:${pluginName}/${pluginName}.plugin.js`); + const bundlePath = addBasePath(`/bundles/plugin/${pluginName}/${pluginName}.plugin.js`); script.setAttribute('src', bundlePath); script.setAttribute('id', `kbn-plugin-${pluginName}`); script.setAttribute('async', ''); diff --git a/src/core/server/http/router/validator/validator.ts b/src/core/server/http/router/validator/validator.ts index 6c766e69f0f37f..a2299b47ae253d 100644 --- a/src/core/server/http/router/validator/validator.ts +++ b/src/core/server/http/router/validator/validator.ts @@ -17,7 +17,14 @@ * under the License. */ -import { ValidationError, Type, schema, ObjectType, isConfigSchema } from '@kbn/config-schema'; +import { + ValidationError, + Type, + schema, + ObjectType, + TypeOf, + isConfigSchema, +} from '@kbn/config-schema'; import { Stream } from 'stream'; import { RouteValidationError } from './validator_error'; @@ -85,7 +92,7 @@ type RouteValidationResultType | undefined> = T extends RouteValidationFunction ? ReturnType['value'] : T extends Type - ? ReturnType + ? TypeOf : undefined >; @@ -170,7 +177,7 @@ export class RouteValidator

{ * @internal */ public getParams(data: unknown, namespace?: string): Readonly

{ - return this.validate(this.config.params, this.options.unsafe?.params, data, namespace); + return this.validate(this.config.params, this.options.unsafe?.params, data, namespace) as P; } /** @@ -178,7 +185,7 @@ export class RouteValidator

{ * @internal */ public getQuery(data: unknown, namespace?: string): Readonly { - return this.validate(this.config.query, this.options.unsafe?.query, data, namespace); + return this.validate(this.config.query, this.options.unsafe?.query, data, namespace) as Q; } /** @@ -186,7 +193,7 @@ export class RouteValidator

{ * @internal */ public getBody(data: unknown, namespace?: string): Readonly { - return this.validate(this.config.body, this.options.unsafe?.body, data, namespace); + return this.validate(this.config.body, this.options.unsafe?.body, data, namespace) as B; } /** diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker b/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker index d4d2e86e1e96bf..38acfb15d3ece2 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker +++ b/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker @@ -195,6 +195,7 @@ kibana_vars=( xpack.reporting.capture.viewport.width xpack.reporting.capture.zoom xpack.reporting.csv.checkForFormulas + xpack.reporting.csv.escapeFormulaValues xpack.reporting.csv.enablePanelActionDownload xpack.reporting.csv.maxSizeBytes xpack.reporting.csv.scroll.duration diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js b/src/legacy/core_plugins/kibana/public/__tests__/vis_type_table/agg_table.js similarity index 94% rename from src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js rename to src/legacy/core_plugins/kibana/public/__tests__/vis_type_table/agg_table.js index a23407a599ae27..b212ecf578dd1f 100644 --- a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js +++ b/src/legacy/core_plugins/kibana/public/__tests__/vis_type_table/agg_table.js @@ -22,11 +22,18 @@ import moment from 'moment'; import ngMock from 'ng_mock'; import expect from '@kbn/expect'; import sinon from 'sinon'; -import { npStart } from '../../legacy_imports'; +import './legacy'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { npStart } from 'ui/new_platform'; import { round } from 'lodash'; -import { getAngularModule } from '../../get_inner_angular'; -import { initTableVisLegacyModule } from '../../table_vis_legacy_module'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { getInnerAngular } from '../../../../../../plugins/vis_type_table/public/get_inner_angular'; + +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { initTableVisLegacyModule } from '../../../../../../plugins/vis_type_table/public/table_vis_legacy_module'; import { tabifiedData } from './tabified_data'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { configureAppAngularModule } from '../../../../../../plugins/kibana_legacy/public/angular'; describe('Table Vis - AggTable Directive', function() { let $rootScope; @@ -34,7 +41,8 @@ describe('Table Vis - AggTable Directive', function() { let settings; const initLocalAngular = () => { - const tableVisModule = getAngularModule('kibana/table_vis', npStart.core); + const tableVisModule = getInnerAngular('kibana/table_vis', npStart.core); + configureAppAngularModule(tableVisModule, npStart.core, true); initTableVisLegacyModule(tableVisModule); }; diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js b/src/legacy/core_plugins/kibana/public/__tests__/vis_type_table/agg_table_group.js similarity index 81% rename from src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js rename to src/legacy/core_plugins/kibana/public/__tests__/vis_type_table/agg_table_group.js index 40a0993ccb0175..3cd7de393d66a8 100644 --- a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js +++ b/src/legacy/core_plugins/kibana/public/__tests__/vis_type_table/agg_table_group.js @@ -20,17 +20,24 @@ import $ from 'jquery'; import ngMock from 'ng_mock'; import expect from '@kbn/expect'; -import { npStart } from '../../legacy_imports'; -import { getAngularModule } from '../../get_inner_angular'; -import { initTableVisLegacyModule } from '../../table_vis_legacy_module'; +import './legacy'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { getInnerAngular } from '../../../../../../plugins/vis_type_table/public/get_inner_angular'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { initTableVisLegacyModule } from '../../../../../../plugins/vis_type_table/public/table_vis_legacy_module'; import { tabifiedData } from './tabified_data'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { npStart } from 'ui/new_platform'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { configureAppAngularModule } from '../../../../../../plugins/kibana_legacy/public/angular'; describe('Table Vis - AggTableGroup Directive', function() { let $rootScope; let $compile; const initLocalAngular = () => { - const tableVisModule = getAngularModule('kibana/table_vis', npStart.core); + const tableVisModule = getInnerAngular('kibana/table_vis', npStart.core); + configureAppAngularModule(tableVisModule, npStart.core, true); initTableVisLegacyModule(tableVisModule); }; diff --git a/src/legacy/core_plugins/vis_type_table/public/legacy.ts b/src/legacy/core_plugins/kibana/public/__tests__/vis_type_table/legacy.ts similarity index 69% rename from src/legacy/core_plugins/vis_type_table/public/legacy.ts rename to src/legacy/core_plugins/kibana/public/__tests__/vis_type_table/legacy.ts index 3d5f8c1b3efe92..c6467a5beae686 100644 --- a/src/legacy/core_plugins/vis_type_table/public/legacy.ts +++ b/src/legacy/core_plugins/kibana/public/__tests__/vis_type_table/legacy.ts @@ -16,19 +16,23 @@ * specific language governing permissions and limitations * under the License. */ - import { PluginInitializerContext } from 'kibana/public'; -import { npSetup, npStart } from './legacy_imports'; -import { plugin } from '.'; - -import { TablePluginSetupDependencies } from './plugin'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { npStart, npSetup } from 'ui/new_platform'; +import { + TableVisPlugin, + TablePluginSetupDependencies, + // eslint-disable-next-line @kbn/eslint/no-restricted-paths +} from '../../../../../../plugins/vis_type_table/public/plugin'; const plugins: Readonly = { expressions: npSetup.plugins.expressions, visualizations: npSetup.plugins.visualizations, }; -const pluginInstance = plugin({} as PluginInitializerContext); +const pluginInstance = new TableVisPlugin({} as PluginInitializerContext); export const setup = pluginInstance.setup(npSetup.core, plugins); -export const start = pluginInstance.start(npStart.core, { data: npStart.plugins.data }); +export const start = pluginInstance.start(npStart.core, { + data: npStart.plugins.data, +}); diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/tabified_data.js b/src/legacy/core_plugins/kibana/public/__tests__/vis_type_table/tabified_data.js similarity index 100% rename from src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/tabified_data.js rename to src/legacy/core_plugins/kibana/public/__tests__/vis_type_table/tabified_data.js diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js index 72276a38f6ac21..56966d6294c9a4 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js @@ -57,7 +57,6 @@ const { core, chrome, data, - docTitle, history, indexPatterns, filterManager, @@ -214,6 +213,7 @@ function discoverController( isAppStateDirty, kbnUrlStateStorage, getPreviousAppState, + resetInitialAppState, } = getState({ defaultAppState: getStateDefaults(), storeInSessionStorage: config.get('state:storeInSessionStorage'), @@ -373,6 +373,8 @@ function discoverController( // If the save wasn't successful, put the original values back. if (!response.id || response.error) { savedSearch.title = currentTitle; + } else { + resetInitialAppState(); } return response; }); @@ -758,7 +760,7 @@ function discoverController( } else { // Update defaults so that "reload saved query" functions correctly setAppState(getStateDefaults()); - docTitle.change(savedSearch.lastSavedTitle); + chrome.docTitle.change(savedSearch.lastSavedTitle); } } }); diff --git a/src/legacy/core_plugins/kibana/public/kibana.js b/src/legacy/core_plugins/kibana/public/kibana.js index 20c46765dcb302..ea0d5ad3790b13 100644 --- a/src/legacy/core_plugins/kibana/public/kibana.js +++ b/src/legacy/core_plugins/kibana/public/kibana.js @@ -49,8 +49,9 @@ import { showAppRedirectNotification } from '../../../../plugins/kibana_legacy/p import 'leaflet'; import { localApplicationService } from './local_application_service'; -npSetup.plugins.kibanaLegacy.forwardApp('doc', 'discover', { keepPrefix: true }); -npSetup.plugins.kibanaLegacy.forwardApp('context', 'discover', { keepPrefix: true }); +npSetup.plugins.kibanaLegacy.registerLegacyAppAlias('doc', 'discover', { keepPrefix: true }); +npSetup.plugins.kibanaLegacy.registerLegacyAppAlias('context', 'discover', { keepPrefix: true }); + localApplicationService.attachToAngular(routes); routes.enable(); diff --git a/src/legacy/core_plugins/kibana/public/local_application_service/local_application_service.ts b/src/legacy/core_plugins/kibana/public/local_application_service/local_application_service.ts index 14564cfd9ee784..f38c410e6832f7 100644 --- a/src/legacy/core_plugins/kibana/public/local_application_service/local_application_service.ts +++ b/src/legacy/core_plugins/kibana/public/local_application_service/local_application_service.ts @@ -98,14 +98,29 @@ export class LocalApplicationService { } }); - npStart.plugins.kibanaLegacy.getForwards().forEach(({ legacyAppId, newAppId, keepPrefix }) => { - angularRouteManager.when(matchAllWithPrefix(legacyAppId), { - resolveRedirectTo: ($location: ILocationService) => { - const url = $location.url(); - return `/${newAppId}${keepPrefix ? url : url.replace(legacyAppId, '')}`; + npStart.plugins.kibanaLegacy.getForwards().forEach(forwardDefinition => { + angularRouteManager.when(matchAllWithPrefix(forwardDefinition.legacyAppId), { + outerAngularWrapperRoute: true, + reloadOnSearch: false, + reloadOnUrl: false, + template: '', + controller($location: ILocationService) { + const newPath = forwardDefinition.rewritePath($location.url()); + npStart.core.application.navigateToApp(forwardDefinition.newAppId, { path: newPath }); }, }); }); + + npStart.plugins.kibanaLegacy + .getLegacyAppAliases() + .forEach(({ legacyAppId, newAppId, keepPrefix }) => { + angularRouteManager.when(matchAllWithPrefix(legacyAppId), { + resolveRedirectTo: ($location: ILocationService) => { + const url = $location.url(); + return `/${newAppId}${keepPrefix ? url : url.replace(legacyAppId, '')}`; + }, + }); + }); } } diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/constants.ts b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/constants.ts new file mode 100644 index 00000000000000..56da031eb4ee86 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/constants.ts @@ -0,0 +1,22 @@ +/* + * 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 TAB_INDEXED_FIELDS = 'indexedFields'; +export const TAB_SCRIPTED_FIELDS = 'scriptedFields'; +export const TAB_SOURCE_FILTERS = 'sourceFilters'; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/create_edit_field.html b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field.html similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/create_edit_field.html rename to src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field.html diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/create_edit_field.js b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/create_edit_field.js deleted file mode 100644 index 95d6cb6878e532..00000000000000 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/create_edit_field.js +++ /dev/null @@ -1,180 +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 { IndexPatternField } from '../../../../../../../../../plugins/data/public'; -import { RegistryFieldFormatEditorsProvider } from 'ui/registry/field_format_editors'; -import { docTitle } from 'ui/doc_title'; -import { KbnUrlProvider } from 'ui/url'; -import uiRoutes from 'ui/routes'; -import { toastNotifications } from 'ui/notify'; -import { npStart } from 'ui/new_platform'; - -import template from './create_edit_field.html'; -import { getEditFieldBreadcrumbs, getCreateFieldBreadcrumbs } from '../../breadcrumbs'; - -import React from 'react'; -import { render, unmountComponentAtNode } from 'react-dom'; -import { FieldEditor } from 'ui/field_editor'; -import { I18nContext } from 'ui/i18n'; -import { i18n } from '@kbn/i18n'; - -import { IndexHeader } from '../index_header'; - -const REACT_FIELD_EDITOR_ID = 'reactFieldEditor'; -const renderFieldEditor = ( - $scope, - indexPattern, - field, - { getConfig, $http, fieldFormatEditors, redirectAway } -) => { - $scope.$$postDigest(() => { - const node = document.getElementById(REACT_FIELD_EDITOR_ID); - if (!node) { - return; - } - - render( - - - - , - node - ); - }); -}; - -const destroyFieldEditor = () => { - const node = document.getElementById(REACT_FIELD_EDITOR_ID); - node && unmountComponentAtNode(node); -}; - -uiRoutes - .when('/management/kibana/index_patterns/:indexPatternId/field/:fieldName*', { - mode: 'edit', - k7Breadcrumbs: getEditFieldBreadcrumbs, - }) - .when('/management/kibana/index_patterns/:indexPatternId/create-field/', { - mode: 'create', - k7Breadcrumbs: getCreateFieldBreadcrumbs, - }) - .defaults(/management\/kibana\/index_patterns\/[^\/]+\/(field|create-field)(\/|$)/, { - template, - mapBreadcrumbs($route, breadcrumbs) { - const { indexPattern } = $route.current.locals; - return breadcrumbs.map(crumb => { - if (crumb.id !== indexPattern.id) { - return crumb; - } - - return { - ...crumb, - display: indexPattern.title, - }; - }); - }, - resolve: { - indexPattern: function($route, Promise, redirectWhenMissing) { - const { indexPatterns } = npStart.plugins.data; - return Promise.resolve(indexPatterns.get($route.current.params.indexPatternId)).catch( - redirectWhenMissing('/management/kibana/index_patterns') - ); - }, - }, - controllerAs: 'fieldSettings', - controller: function FieldEditorPageController( - $scope, - $route, - $timeout, - $http, - Private, - config - ) { - const getConfig = (...args) => config.get(...args); - const fieldFormatEditors = Private(RegistryFieldFormatEditorsProvider); - const kbnUrl = Private(KbnUrlProvider); - - this.mode = $route.current.mode; - this.indexPattern = $route.current.locals.indexPattern; - - if (this.mode === 'edit') { - const fieldName = $route.current.params.fieldName; - this.field = this.indexPattern.fields.getByName(fieldName); - - if (!this.field) { - const message = i18n.translate('kbn.management.editIndexPattern.scripted.noFieldLabel', { - defaultMessage: - "'{indexPatternTitle}' index pattern doesn't have a scripted field called '{fieldName}'", - values: { indexPatternTitle: this.indexPattern.title, fieldName }, - }); - toastNotifications.add(message); - - kbnUrl.redirectToRoute(this.indexPattern, 'edit'); - return; - } - } else if (this.mode === 'create') { - this.field = new IndexPatternField(this.indexPattern, { - scripted: true, - type: 'number', - }); - } else { - const errorMessage = i18n.translate( - 'kbn.management.editIndexPattern.scripted.unknownModeErrorMessage', - { - defaultMessage: 'unknown fieldSettings mode {mode}', - values: { mode: this.mode }, - } - ); - throw new Error(errorMessage); - } - - const fieldName = - this.field.name || - i18n.translate('kbn.management.editIndexPattern.scripted.newFieldPlaceholder', { - defaultMessage: 'New Scripted Field', - }); - docTitle.change([fieldName, this.indexPattern.title]); - - renderFieldEditor($scope, this.indexPattern, this.field, { - getConfig, - $http, - fieldFormatEditors, - redirectAway: () => { - $timeout(() => { - kbnUrl.changeToRoute( - this.indexPattern, - this.field.scripted ? 'scriptedFields' : 'indexedFields' - ); - }); - }, - }); - - $scope.$on('$destroy', () => { - destroyFieldEditor(); - }); - }, - }); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/create_edit_field.tsx b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/create_edit_field.tsx new file mode 100644 index 00000000000000..4839870f0f3c8a --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/create_edit_field.tsx @@ -0,0 +1,111 @@ +/* + * 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 { withRouter, RouteComponentProps } from 'react-router-dom'; +// @ts-ignore +import { FieldEditor } from 'ui/field_editor'; + +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { IndexHeader } from '../index_header'; +import { IndexPattern, IndexPatternField } from '../../../../../../../../../plugins/data/public'; +import { ChromeDocTitle, NotificationsStart } from '../../../../../../../../../core/public'; +import { TAB_SCRIPTED_FIELDS, TAB_INDEXED_FIELDS } from '../constants'; + +interface CreateEditFieldProps extends RouteComponentProps { + indexPattern: IndexPattern; + mode?: string; + fieldName?: string; + fieldFormatEditors: any; + getConfig: (name: string) => any; + services: { + notifications: NotificationsStart; + docTitle: ChromeDocTitle; + http: Function; + }; +} + +const newFieldPlaceholder = i18n.translate( + 'kbn.management.editIndexPattern.scripted.newFieldPlaceholder', + { + defaultMessage: 'New Scripted Field', + } +); + +export const CreateEditField = withRouter( + ({ + indexPattern, + mode, + fieldName, + fieldFormatEditors, + getConfig, + services, + history, + }: CreateEditFieldProps) => { + const field = + mode === 'edit' && fieldName + ? indexPattern.fields.getByName(fieldName) + : new IndexPatternField(indexPattern, { + scripted: true, + type: 'number', + }); + + const url = `/management/kibana/index_patterns/${indexPattern.id}`; + + if (mode === 'edit') { + if (!field) { + const message = i18n.translate('kbn.management.editIndexPattern.scripted.noFieldLabel', { + defaultMessage: + "'{indexPatternTitle}' index pattern doesn't have a scripted field called '{fieldName}'", + values: { indexPatternTitle: indexPattern.title, fieldName }, + }); + services.notifications.toasts.addWarning(message); + history.push(url); + } + } + + const docFieldName = field?.name || newFieldPlaceholder; + + services.docTitle.change([docFieldName, indexPattern.title]); + + const redirectAway = () => { + history.push(`${url}?_a=(tab:${field?.scripted ? TAB_SCRIPTED_FIELDS : TAB_INDEXED_FIELDS})`); + }; + + return ( + + + + + + + + + ); + } +); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/index.js b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/index.ts similarity index 93% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/index.js rename to src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/index.ts index 890a3b2622577b..473a8f5b57c825 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/index.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/index.ts @@ -17,4 +17,4 @@ * under the License. */ -import './create_edit_field'; +export { CreateEditField } from './create_edit_field'; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.js b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.js index 69184a513f53a5..3239a17f109e43 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.js @@ -18,15 +18,18 @@ */ import _ from 'lodash'; +import { HashRouter } from 'react-router-dom'; import { IndexHeader } from './index_header'; -import './create_edit_field'; +import { CreateEditField } from './create_edit_field'; import { docTitle } from 'ui/doc_title'; import { KbnUrlProvider } from 'ui/url'; import { IndicesEditSectionsProvider } from './edit_sections'; import { fatalError, toastNotifications } from 'ui/notify'; +import { RegistryFieldFormatEditorsProvider } from 'ui/registry/field_format_editors'; import uiRoutes from 'ui/routes'; import { uiModules } from 'ui/modules'; import template from './edit_index_pattern.html'; +import createEditFieldtemplate from './create_edit_field.html'; import { fieldWildcardMatcher } from '../../../../../../../../plugins/kibana_utils/public'; import { subscribeWithScope } from '../../../../../../../../plugins/kibana_legacy/public'; import React from 'react'; @@ -37,8 +40,12 @@ import { ScriptedFieldsTable } from './scripted_fields_table'; import { i18n } from '@kbn/i18n'; import { I18nContext } from 'ui/i18n'; import { npStart } from 'ui/new_platform'; - -import { getEditBreadcrumbs } from '../breadcrumbs'; +import { + getEditBreadcrumbs, + getEditFieldBreadcrumbs, + getCreateFieldBreadcrumbs, +} from '../breadcrumbs'; +import { TAB_INDEXED_FIELDS, TAB_SCRIPTED_FIELDS, TAB_SOURCE_FILTERS } from './constants'; import { createEditIndexPatternPageStateContainer } from './edit_index_pattern_state_container'; const REACT_SOURCE_FILTERS_DOM_ELEMENT_ID = 'reactSourceFiltersTable'; @@ -46,10 +53,6 @@ const REACT_INDEXED_FIELDS_DOM_ELEMENT_ID = 'reactIndexedFieldsTable'; const REACT_SCRIPTED_FIELDS_DOM_ELEMENT_ID = 'reactScriptedFieldsTable'; const REACT_INDEX_HEADER_DOM_ELEMENT_ID = 'reactIndexHeader'; -const TAB_INDEXED_FIELDS = 'indexedFields'; -const TAB_SCRIPTED_FIELDS = 'scriptedFields'; -const TAB_SOURCE_FILTERS = 'sourceFilters'; - const EDIT_FIELD_PATH = '/management/kibana/index_patterns/{{indexPattern.id}}/field/{{name}}'; function updateSourceFiltersTable($scope) { @@ -425,3 +428,84 @@ uiModules renderIndexHeader($scope, config); }); + +// routes for create edit field. Will be removed after migartion all component to react. +const REACT_FIELD_EDITOR_ID = 'reactFieldEditor'; +const renderCreateEditField = ($scope, $route, getConfig, $http, fieldFormatEditors) => { + $scope.$$postDigest(() => { + const node = document.getElementById(REACT_FIELD_EDITOR_ID); + if (!node) { + return; + } + + render( + + + + + , + node + ); + }); +}; + +const destroyCreateEditField = () => { + const node = document.getElementById(REACT_FIELD_EDITOR_ID); + node && unmountComponentAtNode(node); +}; + +uiRoutes + .when('/management/kibana/index_patterns/:indexPatternId/field/:fieldName*', { + mode: 'edit', + k7Breadcrumbs: getEditFieldBreadcrumbs, + }) + .when('/management/kibana/index_patterns/:indexPatternId/create-field/', { + mode: 'create', + k7Breadcrumbs: getCreateFieldBreadcrumbs, + }) + .defaults(/management\/kibana\/index_patterns\/[^\/]+\/(field|create-field)(\/|$)/, { + template: createEditFieldtemplate, + mapBreadcrumbs($route, breadcrumbs) { + const { indexPattern } = $route.current.locals; + return breadcrumbs.map(crumb => { + if (crumb.id !== indexPattern.id) { + return crumb; + } + + return { + ...crumb, + display: indexPattern.title, + }; + }); + }, + resolve: { + indexPattern: function($route, Promise, redirectWhenMissing) { + const { indexPatterns } = npStart.plugins.data; + return Promise.resolve(indexPatterns.get($route.current.params.indexPatternId)).catch( + redirectWhenMissing('/management/kibana/index_patterns') + ); + }, + }, + controllerAs: 'fieldSettings', + controller: function FieldEditorPageController($scope, $route, $http, Private, config) { + const getConfig = (...args) => config.get(...args); + const fieldFormatEditors = Private(RegistryFieldFormatEditorsProvider); + + renderCreateEditField($scope, $route, getConfig, $http, fieldFormatEditors); + + $scope.$on('$destroy', () => { + destroyCreateEditField(); + }); + }, + }); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index_header/index_header.tsx b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index_header/index_header.tsx index 866d10ecb0e19d..deac85d9a32e9a 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index_header/index_header.tsx +++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index_header/index_header.tsx @@ -30,8 +30,8 @@ import { import { IIndexPattern } from '../../../../../../../../../plugins/data/public'; interface IndexHeaderProps { - defaultIndex: string; indexPattern: IIndexPattern; + defaultIndex?: string; setDefault?: () => void; refreshFields?: () => void; deleteIndexPattern?: () => void; @@ -77,7 +77,7 @@ export function IndexHeader({ )} - +

{indexPattern.title}

diff --git a/src/legacy/core_plugins/vis_type_table/index.ts b/src/legacy/core_plugins/vis_type_table/index.ts deleted file mode 100644 index 04ca9da7de32b8..00000000000000 --- a/src/legacy/core_plugins/vis_type_table/index.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. - */ - -import { resolve } from 'path'; -import { Legacy } from 'kibana'; - -import { LegacyPluginApi, LegacyPluginInitializer } from '../../../../src/legacy/types'; - -const tableVisPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPluginApi) => - new Plugin({ - id: 'table_vis', - require: ['kibana', 'elasticsearch'], - publicDir: resolve(__dirname, 'public'), - uiExports: { - styleSheetPaths: resolve(__dirname, 'public/index.scss'), - hacks: [resolve(__dirname, 'public/legacy')], - injectDefaultVars: server => ({}), - }, - init: (server: Legacy.Server) => ({}), - config(Joi: any) { - return Joi.object({ - enabled: Joi.boolean().default(true), - }).default(); - }, - } as Legacy.PluginSpecOptions); - -// eslint-disable-next-line import/no-default-export -export default tableVisPluginInitializer; diff --git a/src/legacy/core_plugins/vis_type_table/package.json b/src/legacy/core_plugins/vis_type_table/package.json deleted file mode 100644 index 2809b0e0478365..00000000000000 --- a/src/legacy/core_plugins/vis_type_table/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "table_vis", - "version": "kibana" -} diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/_index.scss b/src/legacy/core_plugins/vis_type_table/public/agg_table/_index.scss deleted file mode 100644 index b19d4a887a7f39..00000000000000 --- a/src/legacy/core_plugins/vis_type_table/public/agg_table/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import 'agg_table'; diff --git a/src/legacy/core_plugins/vis_type_table/public/paginated_table/_index.scss b/src/legacy/core_plugins/vis_type_table/public/paginated_table/_index.scss deleted file mode 100644 index 9473b847d3c2bd..00000000000000 --- a/src/legacy/core_plugins/vis_type_table/public/paginated_table/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import './table_cell_filter'; diff --git a/src/legacy/core_plugins/vis_type_table/public/table_vis_type.ts b/src/legacy/core_plugins/vis_type_table/public/table_vis_type.ts deleted file mode 100644 index 43816121bc23bc..00000000000000 --- a/src/legacy/core_plugins/vis_type_table/public/table_vis_type.ts +++ /dev/null @@ -1,98 +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'; -import { AggGroupNames } from '../../../../plugins/data/public'; -import { Schemas } from '../../../../plugins/vis_default_editor/public'; -import { Vis } from '../../../../plugins/visualizations/public'; -import { tableVisResponseHandler } from './table_vis_response_handler'; -// @ts-ignore -import tableVisTemplate from './table_vis.html'; -import { TableOptions } from './components/table_vis_options'; -import { TableVisualizationController } from './vis_controller'; - -export const tableVisTypeDefinition = { - type: 'table', - name: 'table', - title: i18n.translate('visTypeTable.tableVisTitle', { - defaultMessage: 'Data Table', - }), - icon: 'visTable', - description: i18n.translate('visTypeTable.tableVisDescription', { - defaultMessage: 'Display values in a table', - }), - visualization: TableVisualizationController, - visConfig: { - defaults: { - perPage: 10, - showPartialRows: false, - showMetricsAtAllLevels: false, - sort: { - columnIndex: null, - direction: null, - }, - showTotal: false, - totalFunc: 'sum', - percentageCol: '', - }, - template: tableVisTemplate, - }, - editorConfig: { - optionsTemplate: TableOptions, - schemas: new Schemas([ - { - group: AggGroupNames.Metrics, - name: 'metric', - title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.metricTitle', { - defaultMessage: 'Metric', - }), - aggFilter: ['!geo_centroid', '!geo_bounds'], - aggSettings: { - top_hits: { - allowStrings: true, - }, - }, - min: 1, - defaults: [{ type: 'count', schema: 'metric' }], - }, - { - group: AggGroupNames.Buckets, - name: 'bucket', - title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.bucketTitle', { - defaultMessage: 'Split rows', - }), - aggFilter: ['!filter'], - }, - { - group: AggGroupNames.Buckets, - name: 'split', - title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.splitTitle', { - defaultMessage: 'Split table', - }), - min: 0, - max: 1, - aggFilter: ['!filter'], - }, - ]), - }, - responseHandler: tableVisResponseHandler, - hierarchicalData: (vis: Vis) => { - return Boolean(vis.params.showPartialRows || vis.params.showMetricsAtAllLevels); - }, -}; 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 deleted file mode 100644 index 5bb730d2f9b105..00000000000000 --- a/src/legacy/core_plugins/vis_type_table/public/vis_controller.ts +++ /dev/null @@ -1,104 +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 angular, { IModule, auto, IRootScopeService, IScope, ICompileService } from 'angular'; -import $ from 'jquery'; - -import { VisParams, ExprVis } from '../../../../plugins/visualizations/public'; -import { npStart } from './legacy_imports'; -import { getAngularModule } from './get_inner_angular'; -import { initTableVisLegacyModule } from './table_vis_legacy_module'; - -const innerAngularName = 'kibana/table_vis'; - -export class TableVisualizationController { - private tableVisModule: IModule | undefined; - private injector: auto.IInjectorService | undefined; - el: JQuery; - vis: ExprVis; - $rootScope: IRootScopeService | null = null; - $scope: (IScope & { [key: string]: any }) | undefined; - $compile: ICompileService | undefined; - - constructor(domeElement: Element, vis: ExprVis) { - this.el = $(domeElement); - this.vis = vis; - } - - getInjector() { - if (!this.injector) { - const mountpoint = document.createElement('div'); - mountpoint.setAttribute('style', 'height: 100%; width: 100%;'); - this.injector = angular.bootstrap(mountpoint, [innerAngularName]); - this.el.append(mountpoint); - } - - return this.injector; - } - - initLocalAngular() { - if (!this.tableVisModule) { - this.tableVisModule = getAngularModule(innerAngularName, npStart.core); - initTableVisLegacyModule(this.tableVisModule); - } - } - - async render(esResponse: object, visParams: VisParams) { - this.initLocalAngular(); - - return new Promise(async (resolve, reject) => { - if (!this.$rootScope) { - const $injector = this.getInjector(); - this.$rootScope = $injector.get('$rootScope'); - this.$compile = $injector.get('$compile'); - } - const updateScope = () => { - if (!this.$scope) { - return; - } - this.$scope.vis = this.vis; - this.$scope.visState = { params: visParams }; - this.$scope.esResponse = esResponse; - - this.$scope.visParams = visParams; - this.$scope.renderComplete = resolve; - this.$scope.renderFailed = reject; - this.$scope.resize = Date.now(); - this.$scope.$apply(); - }; - - if (!this.$scope && this.$compile) { - 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.$scope.$apply(); - } else { - updateScope(); - } - }); - } - - destroy() { - if (this.$rootScope) { - this.$rootScope.$destroy(); - this.$rootScope = null; - } - } -} diff --git a/src/legacy/ui/public/new_platform/new_platform.karma_mock.js b/src/legacy/ui/public/new_platform/new_platform.karma_mock.js index f577a29ce90b91..f14f26613ef019 100644 --- a/src/legacy/ui/public/new_platform/new_platform.karma_mock.js +++ b/src/legacy/ui/public/new_platform/new_platform.karma_mock.js @@ -242,6 +242,7 @@ export const npSetup = { }, kibanaLegacy: { registerLegacyApp: () => {}, + registerLegacyAppAlias: () => {}, forwardApp: () => {}, config: { defaultAppId: 'home', @@ -362,6 +363,7 @@ export const npStart = { kibanaLegacy: { getApps: () => [], getForwards: () => [], + getLegacyAppAliases: () => [], config: { defaultAppId: 'home', }, diff --git a/src/legacy/ui/ui_render/bootstrap/template.js.hbs b/src/legacy/ui/ui_render/bootstrap/template.js.hbs index 4557d911620a23..1093153edbbf7e 100644 --- a/src/legacy/ui/ui_render/bootstrap/template.js.hbs +++ b/src/legacy/ui/ui_render/bootstrap/template.js.hbs @@ -78,10 +78,10 @@ if (window.__kbnStrictCsp__ && window.__kbnCspNotEnforced__) { '{{this}}', {{/each}} '{{regularBundlePath}}/commons.bundle.js', - {{!-- '{{regularBundlePath}}/plugin:data/data.plugin.js', --}} - '{{regularBundlePath}}/plugin:kibanaUtils/kibanaUtils.plugin.js', - '{{regularBundlePath}}/plugin:esUiShared/esUiShared.plugin.js', - '{{regularBundlePath}}/plugin:kibanaReact/kibanaReact.plugin.js' + {{!-- '{{regularBundlePath}}/plugin/data/data.plugin.js', --}} + '{{regularBundlePath}}/plugin/kibanaUtils/kibanaUtils.plugin.js', + '{{regularBundlePath}}/plugin/esUiShared/esUiShared.plugin.js', + '{{regularBundlePath}}/plugin/kibanaReact/kibanaReact.plugin.js' ], function () { load([ '{{regularBundlePath}}/{{appId}}.bundle.js', diff --git a/src/optimize/bundles_route/bundles_route.js b/src/optimize/bundles_route/bundles_route.js index f4e3108f80a3b8..0c2e98b5acd63c 100644 --- a/src/optimize/bundles_route/bundles_route.js +++ b/src/optimize/bundles_route/bundles_route.js @@ -79,8 +79,8 @@ export function createBundlesRoute({ ), ...npUiPluginPublicDirs.map(({ id, path }) => buildRouteForBundles( - `${basePublicPath}/bundles/plugin:${id}/`, - `/bundles/plugin:${id}/`, + `${basePublicPath}/bundles/plugin/${id}/`, + `/bundles/plugin/${id}/`, path, fileHashCache ) diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index b62b728beca35f..05a4141483587f 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -293,6 +293,7 @@ import { convertIPRangeToString, intervalOptions, // only used in Discover isDateHistogramBucketAggConfig, + isNumberType, isStringType, isType, parentPipelineType, @@ -392,6 +393,7 @@ export const search = { InvalidEsCalendarIntervalError, InvalidEsIntervalFormatError, isDateHistogramBucketAggConfig, + isNumberType, isStringType, isType, isValidEsInterval, diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 427c4f7864554d..6383f618641469 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -1545,8 +1545,9 @@ export const search: { InvalidEsCalendarIntervalError: typeof InvalidEsCalendarIntervalError; InvalidEsIntervalFormatError: typeof InvalidEsIntervalFormatError; isDateHistogramBucketAggConfig: typeof isDateHistogramBucketAggConfig; + isNumberType: (agg: import("./search").AggConfig) => boolean; isStringType: (agg: import("./search").AggConfig) => boolean; - isType: (type: string) => (agg: import("./search").AggConfig) => boolean; + isType: (...types: string[]) => (agg: import("./search").AggConfig) => boolean; isValidEsInterval: typeof isValidEsInterval; isValidInterval: typeof isValidInterval; parentPipelineType: string; @@ -1874,21 +1875,21 @@ export type TSearchStrategyProvider = (context: ISearc // src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "getRoutes" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "formatHitProvider" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:382:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:382:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:382:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:382:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:387:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:388:1 - (ae-forgotten-export) The symbol "convertDateRangeToString" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:390:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:399:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:400:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:401:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:404:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:405:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:408:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:409:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:412:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:383:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:383:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:383:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:383:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:388:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:389:1 - (ae-forgotten-export) The symbol "convertDateRangeToString" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:391:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:400:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:401:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:402:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:406:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:407:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:410:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:411:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:414:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts // src/plugins/data/public/query/state_sync/connect_to_query_state.ts:33:33 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts // src/plugins/data/public/query/state_sync/connect_to_query_state.ts:37:1 - (ae-forgotten-export) The symbol "QueryStateChange" needs to be exported by the entry point index.d.ts // src/plugins/data/public/types.ts:52:5 - (ae-forgotten-export) The symbol "createFiltersFromEvent" needs to be exported by the entry point index.d.ts diff --git a/src/plugins/data/public/search/aggs/buckets/migrate_include_exclude_format.ts b/src/plugins/data/public/search/aggs/buckets/migrate_include_exclude_format.ts index 0beeb1c3722752..116f8cfad60f6d 100644 --- a/src/plugins/data/public/search/aggs/buckets/migrate_include_exclude_format.ts +++ b/src/plugins/data/public/search/aggs/buckets/migrate_include_exclude_format.ts @@ -21,20 +21,22 @@ import { isString, isObject } from 'lodash'; import { IBucketAggConfig, BucketAggType, BucketAggParam } from './bucket_agg_type'; import { IAggConfig } from '../agg_config'; -export const isType = (type: string) => { +export const isType = (...types: string[]) => { return (agg: IAggConfig): boolean => { const field = agg.params.field; - return field && field.type === type; + return types.some(type => field && field.type === type); }; }; +export const isNumberType = isType('number'); export const isStringType = isType('string'); +export const isStringOrNumberType = isType('string', 'number'); export const migrateIncludeExcludeFormat = { serialize(this: BucketAggParam, value: any, agg: IBucketAggConfig) { if (this.shouldShow && !this.shouldShow(agg)) return; - if (!value || isString(value)) return value; + if (!value || isString(value) || Array.isArray(value)) return value; else return value.pattern; }, write( @@ -44,7 +46,12 @@ export const migrateIncludeExcludeFormat = { ) { const value = aggConfig.getParam(this.name); - if (isObject(value)) { + if (Array.isArray(value) && value.length > 0 && isNumberType(aggConfig)) { + const parsedValue = value.filter((val): val is number => Number.isFinite(val)); + if (parsedValue.length) { + output.params[this.name] = parsedValue; + } + } else if (isObject(value)) { output.params[this.name] = value.pattern; } else if (value && isStringType(aggConfig)) { output.params[this.name] = value; diff --git a/src/plugins/data/public/search/aggs/buckets/terms.test.ts b/src/plugins/data/public/search/aggs/buckets/terms.test.ts index 0dc052bd1fdf6d..9769efb6da7494 100644 --- a/src/plugins/data/public/search/aggs/buckets/terms.test.ts +++ b/src/plugins/data/public/search/aggs/buckets/terms.test.ts @@ -75,5 +75,65 @@ describe('Terms Agg', () => { expect(params.include).toBe('404'); expect(params.exclude).toBe('400'); }); + + test('accepts string from string field type and writes this value', () => { + const aggConfigs = getAggConfigs({ + include: 'include value', + exclude: 'exclude value', + field: { + name: 'string_field', + type: 'string', + }, + orderAgg: { + type: 'count', + }, + }); + + const { [BUCKET_TYPES.TERMS]: params } = aggConfigs.aggs[0].toDsl(); + + expect(params.field).toBe('string_field'); + expect(params.include).toBe('include value'); + expect(params.exclude).toBe('exclude value'); + }); + + test('accepts empty array from number field type and does not write a value', () => { + const aggConfigs = getAggConfigs({ + include: [], + exclude: [], + field: { + name: 'empty_number_field', + type: 'number', + }, + orderAgg: { + type: 'count', + }, + }); + + const { [BUCKET_TYPES.TERMS]: params } = aggConfigs.aggs[0].toDsl(); + + expect(params.field).toBe('empty_number_field'); + expect(params.include).toBe(undefined); + expect(params.exclude).toBe(undefined); + }); + + test('filters array with empty strings from number field type and writes only numbers', () => { + const aggConfigs = getAggConfigs({ + include: [1.1, 2, '', 3.33, ''], + exclude: ['', 4, 5.555, '', 6], + field: { + name: 'number_field', + type: 'number', + }, + orderAgg: { + type: 'count', + }, + }); + + const { [BUCKET_TYPES.TERMS]: params } = aggConfigs.aggs[0].toDsl(); + + expect(params.field).toBe('number_field'); + expect(params.include).toStrictEqual([1.1, 2, 3.33]); + expect(params.exclude).toStrictEqual([4, 5.555, 6]); + }); }); }); diff --git a/src/plugins/data/public/search/aggs/buckets/terms.ts b/src/plugins/data/public/search/aggs/buckets/terms.ts index 5baa38af0e8d61..698e0dfb1d3404 100644 --- a/src/plugins/data/public/search/aggs/buckets/terms.ts +++ b/src/plugins/data/public/search/aggs/buckets/terms.ts @@ -22,7 +22,10 @@ import { i18n } from '@kbn/i18n'; import { BucketAggType, IBucketAggConfig } from './bucket_agg_type'; import { BUCKET_TYPES } from './bucket_agg_types'; import { createFilterTerms } from './create_filter/terms'; -import { isStringType, migrateIncludeExcludeFormat } from './migrate_include_exclude_format'; +import { + isStringOrNumberType, + migrateIncludeExcludeFormat, +} from './migrate_include_exclude_format'; import { IAggConfigs } from '../agg_configs'; import { Adapters } from '../../../../../inspector/public'; @@ -266,7 +269,7 @@ export const getTermsBucketAgg = ({ getInternalStartServices }: TermsBucketAggDe }), type: 'string', advanced: true, - shouldShow: isStringType, + shouldShow: isStringOrNumberType, ...migrateIncludeExcludeFormat, }, { @@ -276,7 +279,7 @@ export const getTermsBucketAgg = ({ getInternalStartServices }: TermsBucketAggDe }), type: 'string', advanced: true, - shouldShow: isStringType, + shouldShow: isStringOrNumberType, ...migrateIncludeExcludeFormat, }, ], diff --git a/src/plugins/expressions/kibana.json b/src/plugins/expressions/kibana.json index cba693dd4bc201..5d2112103e94d3 100644 --- a/src/plugins/expressions/kibana.json +++ b/src/plugins/expressions/kibana.json @@ -4,7 +4,6 @@ "server": true, "ui": true, "requiredPlugins": [ - "bfetch", - "inspector" + "bfetch" ] } diff --git a/src/plugins/expressions/public/loader.ts b/src/plugins/expressions/public/loader.ts index fbe2f37c648d6a..418ff6fdf86145 100644 --- a/src/plugins/expressions/public/loader.ts +++ b/src/plugins/expressions/public/loader.ts @@ -19,13 +19,14 @@ import { BehaviorSubject, Observable, Subject } from 'rxjs'; import { filter, map } from 'rxjs/operators'; -import { Adapters, InspectorSession } from '../../inspector/public'; -import { ExpressionRenderHandler } from './render'; +import { Adapters } from '../../inspector/public'; import { IExpressionLoaderParams } from './types'; import { ExpressionAstExpression } from '../common'; -import { getInspector, getExpressionsService } from './services'; import { ExecutionContract } from '../common/execution/execution_contract'; +import { ExpressionRenderHandler } from './render'; +import { getExpressionsService } from './services'; + type Data = any; export class ExpressionLoader { @@ -120,15 +121,6 @@ export class ExpressionLoader { return this.renderHandler.getElement(); } - openInspector(title: string): InspectorSession | undefined { - const inspector = this.inspect(); - if (inspector) { - return getInspector().open(inspector, { - title, - }); - } - } - inspect(): Adapters | undefined { return this.execution ? (this.execution.inspect() as Adapters) : undefined; } diff --git a/src/plugins/expressions/public/mocks.tsx b/src/plugins/expressions/public/mocks.tsx index cb7089f814643e..b8f2f693e9c778 100644 --- a/src/plugins/expressions/public/mocks.tsx +++ b/src/plugins/expressions/public/mocks.tsx @@ -22,7 +22,6 @@ import { ExpressionsSetup, ExpressionsStart, plugin as pluginInitializer } from /* eslint-disable */ import { coreMock } from '../../../core/public/mocks'; -import { inspectorPluginMock } from '../../inspector/public/mocks'; import { bfetchPluginMock } from '../../bfetch/public/mocks'; /* eslint-enable */ @@ -89,7 +88,6 @@ const createPlugin = async () => { const plugin = pluginInitializer(pluginInitializerContext); const setup = await plugin.setup(coreSetup, { bfetch: bfetchPluginMock.createSetupContract(), - inspector: inspectorPluginMock.createSetupContract(), }); return { @@ -101,7 +99,6 @@ const createPlugin = async () => { doStart: async () => await plugin.start(coreStart, { bfetch: bfetchPluginMock.createStartContract(), - inspector: inspectorPluginMock.createStartContract(), }), }; }; diff --git a/src/plugins/expressions/public/plugin.ts b/src/plugins/expressions/public/plugin.ts index 7c0de271b77060..720c3b701d5046 100644 --- a/src/plugins/expressions/public/plugin.ts +++ b/src/plugins/expressions/public/plugin.ts @@ -29,11 +29,9 @@ import { ExpressionsServiceStart, ExecutionContext, } from '../common'; -import { Setup as InspectorSetup, Start as InspectorStart } from '../../inspector/public'; import { BfetchPublicSetup, BfetchPublicStart } from '../../bfetch/public'; import { setCoreStart, - setInspector, setInterpreter, setRenderersRegistry, setNotifications, @@ -45,12 +43,10 @@ import { render, ExpressionRenderHandler } from './render'; export interface ExpressionsSetupDeps { bfetch: BfetchPublicSetup; - inspector: InspectorSetup; } export interface ExpressionsStartDeps { bfetch: BfetchPublicStart; - inspector: InspectorStart; } export interface ExpressionsSetup extends ExpressionsServiceSetup { @@ -120,7 +116,7 @@ export class ExpressionsPublicPlugin }); } - public setup(core: CoreSetup, { inspector, bfetch }: ExpressionsSetupDeps): ExpressionsSetup { + public setup(core: CoreSetup, { bfetch }: ExpressionsSetupDeps): ExpressionsSetup { this.configureExecutor(core); const { expressions } = this; @@ -180,9 +176,8 @@ export class ExpressionsPublicPlugin return Object.freeze(setup); } - public start(core: CoreStart, { inspector, bfetch }: ExpressionsStartDeps): ExpressionsStart { + public start(core: CoreStart, { bfetch }: ExpressionsStartDeps): ExpressionsStart { setCoreStart(core); - setInspector(inspector); setNotifications(core.notifications); const { expressions } = this; diff --git a/src/plugins/expressions/public/react_expression_renderer.tsx b/src/plugins/expressions/public/react_expression_renderer.tsx index 242a49c6d66394..2c99f173c9f330 100644 --- a/src/plugins/expressions/public/react_expression_renderer.tsx +++ b/src/plugins/expressions/public/react_expression_renderer.tsx @@ -17,8 +17,7 @@ * under the License. */ -import { useRef, useEffect, useState, useLayoutEffect } from 'react'; -import React from 'react'; +import React, { useRef, useEffect, useState, useLayoutEffect } from 'react'; import classNames from 'classnames'; import { Subscription } from 'rxjs'; import { filter } from 'rxjs/operators'; diff --git a/src/plugins/expressions/public/render.ts b/src/plugins/expressions/public/render.ts index ad4d16bcd13234..4aaf0da60fc606 100644 --- a/src/plugins/expressions/public/render.ts +++ b/src/plugins/expressions/public/render.ts @@ -21,10 +21,11 @@ import * as Rx from 'rxjs'; import { Observable } from 'rxjs'; import { filter } from 'rxjs/operators'; import { RenderError, RenderErrorHandlerFnType, IExpressionLoaderParams } from './types'; -import { getRenderersRegistry } from './services'; import { renderErrorHandler as defaultRenderErrorHandler } from './render_error_handler'; import { IInterpreterRenderHandlers, ExpressionAstExpression } from '../common'; +import { getRenderersRegistry } from './services'; + export type IExpressionRendererExtraHandlers = Record; export interface ExpressionRenderHandlerParams { diff --git a/src/plugins/expressions/public/services.ts b/src/plugins/expressions/public/services.ts index a203e874145718..016456c9566660 100644 --- a/src/plugins/expressions/public/services.ts +++ b/src/plugins/expressions/public/services.ts @@ -20,14 +20,11 @@ import { NotificationsStart } from 'kibana/public'; import { createKibanaUtilsCore, createGetterSetter } from '../../kibana_utils/public'; import { ExpressionInterpreter } from './types'; -import { Start as IInspector } from '../../inspector/public'; import { ExpressionsSetup } from './plugin'; import { ExpressionsService } from '../common'; export const { getCoreStart, setCoreStart } = createKibanaUtilsCore(); -export const [getInspector, setInspector] = createGetterSetter('Inspector'); - export const [getInterpreter, setInterpreter] = createGetterSetter( 'Interpreter' ); diff --git a/src/plugins/kibana_legacy/public/angular/angular_config.tsx b/src/plugins/kibana_legacy/public/angular/angular_config.tsx index 71cd57ef2d72ec..295cf27688c805 100644 --- a/src/plugins/kibana_legacy/public/angular/angular_config.tsx +++ b/src/plugins/kibana_legacy/public/angular/angular_config.tsx @@ -92,9 +92,9 @@ export const configureAppAngularModule = ( ) => { const core = 'core' in newPlatform ? newPlatform.core : newPlatform; const packageInfo = - 'injectedMetadata' in newPlatform - ? newPlatform.injectedMetadata.getLegacyMetadata() - : newPlatform.env.packageInfo; + 'env' in newPlatform + ? newPlatform.env.packageInfo + : newPlatform.injectedMetadata.getLegacyMetadata(); if ('injectedMetadata' in newPlatform) { forOwn(newPlatform.injectedMetadata.getInjectedVars(), (val, name) => { diff --git a/src/plugins/kibana_legacy/public/mocks.ts b/src/plugins/kibana_legacy/public/mocks.ts index 8e9a05b186191f..2fdd0d8b4be590 100644 --- a/src/plugins/kibana_legacy/public/mocks.ts +++ b/src/plugins/kibana_legacy/public/mocks.ts @@ -25,6 +25,7 @@ export type Start = jest.Mocked>; const createSetupContract = (): Setup => ({ forwardApp: jest.fn(), + registerLegacyAppAlias: jest.fn(), registerLegacyApp: jest.fn(), config: { defaultAppId: 'home', @@ -37,6 +38,7 @@ const createSetupContract = (): Setup => ({ const createStartContract = (): Start => ({ getApps: jest.fn(), + getLegacyAppAliases: jest.fn(), getForwards: jest.fn(), config: { defaultAppId: 'home', diff --git a/src/plugins/kibana_legacy/public/plugin.ts b/src/plugins/kibana_legacy/public/plugin.ts index 2ad620f355848a..831fc3f0d4a71f 100644 --- a/src/plugins/kibana_legacy/public/plugin.ts +++ b/src/plugins/kibana_legacy/public/plugin.ts @@ -28,12 +28,18 @@ import { Observable } from 'rxjs'; import { ConfigSchema } from '../config'; import { getDashboardConfig } from './dashboard_config'; -interface ForwardDefinition { +interface LegacyAppAliasDefinition { legacyAppId: string; newAppId: string; keepPrefix: boolean; } +interface ForwardDefinition { + legacyAppId: string; + newAppId: string; + rewritePath: (legacyPath: string) => string; +} + export type AngularRenderedAppUpdater = ( app: AppBase ) => Partial | undefined; @@ -54,7 +60,8 @@ export interface AngularRenderedApp extends App { export class KibanaLegacyPlugin { private apps: AngularRenderedApp[] = []; - private forwards: ForwardDefinition[] = []; + private legacyAppAliases: LegacyAppAliasDefinition[] = []; + private forwardDefinitions: ForwardDefinition[] = []; constructor(private readonly initializerContext: PluginInitializerContext) {} @@ -94,17 +101,55 @@ export class KibanaLegacyPlugin { * renaming or nesting plugins. For route changes after the prefix, please * use the routing mechanism of your app. * + * This method just redirects URLs within the legacy `kibana` app. + * * @param legacyAppId The name of the old app to forward URLs from * @param newAppId The name of the new app that handles the URLs now * @param options Whether the prefix of the old app is kept to nest the legacy * path into the new path */ - forwardApp: ( + registerLegacyAppAlias: ( legacyAppId: string, newAppId: string, options: { keepPrefix: boolean } = { keepPrefix: false } ) => { - this.forwards.push({ legacyAppId, newAppId, ...options }); + this.legacyAppAliases.push({ legacyAppId, newAppId, ...options }); + }, + + /** + * Forwards URLs within the legacy `kibana` app to a new platform application. + * + * @param legacyAppId The name of the old app to forward URLs from + * @param newAppId The name of the new app that handles the URLs now + * @param rewritePath Function to rewrite the legacy sub path of the app to the new path in the core app + * path into the new path + * + * Example usage: + * ``` + * kibanaLegacy.forwardApp( + * 'old', + * 'new', + * path => { + * const [, id] = /old/item\/(.*)$/.exec(path) || []; + * if (!id) { + * return '#/home'; + * } + * return '#/items/${id}'; + * } + * ); + * ``` + * This will cause the following redirects: + * + * * app/kibana#/old/ -> app/new#/home + * * app/kibana#/old/item/123 -> app/new#/items/123 + * + */ + forwardApp: ( + legacyAppId: string, + newAppId: string, + rewritePath: (legacyPath: string) => string + ) => { + this.forwardDefinitions.push({ legacyAppId, newAppId, rewritePath }); }, /** @@ -132,7 +177,12 @@ export class KibanaLegacyPlugin { * @deprecated * Just exported for wiring up with legacy platform, should not be used. */ - getForwards: () => this.forwards, + getLegacyAppAliases: () => this.legacyAppAliases, + /** + * @deprecated + * Just exported for wiring up with legacy platform, should not be used. + */ + getForwards: () => this.forwardDefinitions, config: this.initializerContext.config.get(), dashboardConfig: getDashboardConfig(!application.capabilities.dashboard.showWriteControls), }; diff --git a/src/plugins/kibana_utils/public/core/create_start_service_getter.ts b/src/plugins/kibana_utils/public/core/create_start_service_getter.ts index e507d1ae778e59..5e385eb5ed4732 100644 --- a/src/plugins/kibana_utils/public/core/create_start_service_getter.ts +++ b/src/plugins/kibana_utils/public/core/create_start_service_getter.ts @@ -30,6 +30,48 @@ export type StartServicesGetter = () = OwnContract >; +/** + * Use this utility to create a synchronous *start* service getter in *setup* + * life-cycle of your plugin. + * + * Below is a usage example in a Kibana plugin. + * + * ```ts + * export interface MyPluginStartDeps { + * data: DataPublicPluginStart; + * expressions: ExpressionsStart; + * inspector: InspectorStart; + * uiActions: UiActionsStart; + * } + * + * class MyPlugin implements Plugin { + * setup(core: CoreSetup, plugins) { + * const start = createStartServicesGetter(core.getStartServices); + * plugins.expressions.registerFunction(myExpressionFunction(start)); + * } + * + * start(core, plugins: MyPluginStartDeps) { + * + * } + * } + * ``` + * + * In `myExpressionFunction` you can make sure you are picking only the dependencies + * your function needs using the `Pick` type. + * + * ```ts + * const myExpressionFunction = + * (start: StartServicesGetter>) => { + * + * start().plugins.indexPatterns.something(123); + * } + * ``` + * + * @param accessor Asynchronous start service accessor provided by platform. + * @returns Returns a function which synchronously returns *start* core services + * and plugin contracts. If you call this function before the *start* life-cycle + * has started it will throw. + */ export const createStartServicesGetter = ( accessor: StartServicesAccessor ): StartServicesGetter => { diff --git a/src/plugins/telemetry/server/config.ts b/src/plugins/telemetry/server/config.ts index 9621a8b5619b2b..99dde0c3b3d966 100644 --- a/src/plugins/telemetry/server/config.ts +++ b/src/plugins/telemetry/server/config.ts @@ -36,8 +36,8 @@ export const configSchema = schema.object({ config: schema.string({ defaultValue: getConfigPath() }), banner: schema.boolean({ defaultValue: true }), url: schema.conditional( - schema.contextRef('dev'), - schema.literal(true), + schema.contextRef('dist'), + schema.literal(false), // Point to staging if it's not a distributable release schema.string({ defaultValue: `https://telemetry-staging.elastic.co/xpack/${ENDPOINT_VERSION}/send`, }), @@ -46,8 +46,8 @@ export const configSchema = schema.object({ }) ), optInStatusUrl: schema.conditional( - schema.contextRef('dev'), - schema.literal(true), + schema.contextRef('dist'), + schema.literal(false), // Point to staging if it's not a distributable release schema.string({ defaultValue: `https://telemetry-staging.elastic.co/opt_in_status/${ENDPOINT_VERSION}/send`, }), diff --git a/src/plugins/telemetry_collection_manager/server/encryption/encrypt.test.ts b/src/plugins/telemetry_collection_manager/server/encryption/encrypt.test.ts index c04625eb1dd427..6d64268569e06b 100644 --- a/src/plugins/telemetry_collection_manager/server/encryption/encrypt.test.ts +++ b/src/plugins/telemetry_collection_manager/server/encryption/encrypt.test.ts @@ -22,14 +22,14 @@ import { encryptTelemetry, getKID } from './encrypt'; describe('getKID', () => { it(`returns 'kibana_dev' kid for development`, async () => { - const isProd = false; - const kid = getKID(isProd); + const useProdKey = false; + const kid = getKID(useProdKey); expect(kid).toBe('kibana_dev'); }); it(`returns 'kibana_prod' kid for development`, async () => { - const isProd = true; - const kid = getKID(isProd); + const useProdKey = true; + const kid = getKID(useProdKey); expect(kid).toBe('kibana'); }); }); @@ -41,19 +41,19 @@ describe('encryptTelemetry', () => { it('encrypts payload', async () => { const payload = { some: 'value' }; - await encryptTelemetry(payload, { isProd: true }); + await encryptTelemetry(payload, { useProdKey: true }); expect(createRequestEncryptor).toBeCalledWith(telemetryJWKS); }); - it('uses kibana kid on { isProd: true }', async () => { + it('uses kibana kid on { useProdKey: true }', async () => { const payload = { some: 'value' }; - await encryptTelemetry(payload, { isProd: true }); + await encryptTelemetry(payload, { useProdKey: true }); expect(mockEncrypt).toBeCalledWith('kibana', payload); }); - it('uses kibana_dev kid on { isProd: false }', async () => { + it('uses kibana_dev kid on { useProdKey: false }', async () => { const payload = { some: 'value' }; - await encryptTelemetry(payload, { isProd: false }); + await encryptTelemetry(payload, { useProdKey: false }); expect(mockEncrypt).toBeCalledWith('kibana_dev', payload); }); }); diff --git a/src/plugins/telemetry_collection_manager/server/encryption/encrypt.ts b/src/plugins/telemetry_collection_manager/server/encryption/encrypt.ts index 44f053064cfcbd..89f34d794f0593 100644 --- a/src/plugins/telemetry_collection_manager/server/encryption/encrypt.ts +++ b/src/plugins/telemetry_collection_manager/server/encryption/encrypt.ts @@ -20,12 +20,15 @@ import { createRequestEncryptor } from '@elastic/request-crypto'; import { telemetryJWKS } from './telemetry_jwks'; -export function getKID(isProd = false): string { - return isProd ? 'kibana' : 'kibana_dev'; +export function getKID(useProdKey = false): string { + return useProdKey ? 'kibana' : 'kibana_dev'; } -export async function encryptTelemetry(payload: any, { isProd = false } = {}): Promise { - const kid = getKID(isProd); +export async function encryptTelemetry( + payload: any, + { useProdKey = false } = {} +): Promise { + const kid = getKID(useProdKey); const encryptor = await createRequestEncryptor(telemetryJWKS); const clusters = [].concat(payload); return Promise.all(clusters.map((cluster: any) => encryptor.encrypt(kid, cluster))); diff --git a/src/plugins/telemetry_collection_manager/server/plugin.ts b/src/plugins/telemetry_collection_manager/server/plugin.ts index f2f20e215c5351..0b57fae83c0fb4 100644 --- a/src/plugins/telemetry_collection_manager/server/plugin.ts +++ b/src/plugins/telemetry_collection_manager/server/plugin.ts @@ -50,12 +50,12 @@ export class TelemetryCollectionManagerPlugin private readonly collections: Array> = []; private usageGetterMethodPriority = -1; private usageCollection?: UsageCollectionSetup; - private readonly isDev: boolean; + private readonly isDistributable: boolean; private readonly version: string; constructor(initializerContext: PluginInitializerContext) { this.logger = initializerContext.logger.get(); - this.isDev = initializerContext.env.mode.dev; + this.isDistributable = initializerContext.env.packageInfo.dist; this.version = initializerContext.env.packageInfo.version; } @@ -158,7 +158,7 @@ export class TelemetryCollectionManagerPlugin if (config.unencrypted) { return optInStats; } - return encryptTelemetry(optInStats, { isProd: !this.isDev }); + return encryptTelemetry(optInStats, { useProdKey: this.isDistributable }); } } catch (err) { this.logger.debug(`Failed to collect any opt in stats with registered collections.`); @@ -176,7 +176,6 @@ export class TelemetryCollectionManagerPlugin ) => { const context: StatsCollectionContext = { logger: this.logger.get(collection.title), - isDev: this.isDev, version: this.version, ...collection.customContext, }; @@ -206,7 +205,7 @@ export class TelemetryCollectionManagerPlugin return usageData; } - return encryptTelemetry(usageData, { isProd: !this.isDev }); + return encryptTelemetry(usageData, { useProdKey: this.isDistributable }); } } catch (err) { this.logger.debug( @@ -225,7 +224,6 @@ export class TelemetryCollectionManagerPlugin ): Promise { const context: StatsCollectionContext = { logger: this.logger.get(collection.title), - isDev: this.isDev, version: this.version, ...collection.customContext, }; diff --git a/src/plugins/telemetry_collection_manager/server/types.ts b/src/plugins/telemetry_collection_manager/server/types.ts index e23d6a4c388f41..d3a47694d38a76 100644 --- a/src/plugins/telemetry_collection_manager/server/types.ts +++ b/src/plugins/telemetry_collection_manager/server/types.ts @@ -101,7 +101,6 @@ export interface ESLicense { export interface StatsCollectionContext { logger: Logger; - isDev: boolean; version: string; } diff --git a/src/plugins/vis_default_editor/public/components/agg_params_map.ts b/src/plugins/vis_default_editor/public/components/agg_params_map.ts index 5af3cfc5b09289..9bc3146b9903bb 100644 --- a/src/plugins/vis_default_editor/public/components/agg_params_map.ts +++ b/src/plugins/vis_default_editor/public/components/agg_params_map.ts @@ -58,6 +58,8 @@ const buckets = { size: controls.SizeParamEditor, }, [BUCKET_TYPES.TERMS]: { + include: controls.IncludeExcludeParamEditor, + exclude: controls.IncludeExcludeParamEditor, orderBy: controls.OrderByParamEditor, orderAgg: controls.OrderAggParamEditor, order: wrapWithInlineComp(controls.OrderParamEditor), diff --git a/src/plugins/vis_default_editor/public/components/controls/components/number_list/utils.ts b/src/plugins/vis_default_editor/public/components/controls/components/number_list/utils.ts index dac86249ebbb99..5cb594ade8dba7 100644 --- a/src/plugins/vis_default_editor/public/components/controls/components/number_list/utils.ts +++ b/src/plugins/vis_default_editor/public/components/controls/components/number_list/utils.ts @@ -119,7 +119,7 @@ function getNextModel(list: NumberRowModel[], range: NumberListRange): NumberRow }; } -function getInitModelList(list: Array): NumberRowModel[] { +function getInitModelList(list: Array): NumberRowModel[] { return list.length ? list.map(num => ({ value: (num === undefined ? EMPTY_STRING : num) as NumberRowModel['value'], diff --git a/src/plugins/vis_default_editor/public/components/controls/components/simple_number_list.tsx b/src/plugins/vis_default_editor/public/components/controls/components/simple_number_list.tsx new file mode 100644 index 00000000000000..becf8e47ef5736 --- /dev/null +++ b/src/plugins/vis_default_editor/public/components/controls/components/simple_number_list.tsx @@ -0,0 +1,140 @@ +/* + * 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, { Fragment, useCallback, useEffect, useMemo, useState } from 'react'; +import { isArray } from 'lodash'; +import { EuiButtonEmpty, EuiFlexItem, EuiFormRow, EuiSpacer, htmlIdGenerator } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EMPTY_STRING, getInitModelList, getRange, parse } from './number_list/utils'; +import { NumberRow, NumberRowModel } from './number_list/number_row'; +import { AggParamEditorProps } from '../../agg_param_props'; + +const generateId = htmlIdGenerator(); + +function SimpleNumberList({ + agg, + aggParam, + value, + setValue, + setTouched, +}: AggParamEditorProps>) { + const [numbers, setNumbers] = useState( + getInitModelList(value && isArray(value) ? value : [EMPTY_STRING]) + ); + const numberRange = useMemo(() => getRange('[-Infinity,Infinity]'), []); + + // This useEffect is needed to discard changes, it sets numbers a mapped value if they are different + useEffect(() => { + if ( + isArray(value) && + (value.length !== numbers.length || + !value.every((numberValue, index) => numberValue === numbers[index].value)) + ) { + setNumbers( + value.map(numberValue => ({ + id: generateId(), + value: numberValue, + isInvalid: false, + })) + ); + } + }, [numbers, value]); + + const onUpdate = useCallback( + (numberList: NumberRowModel[]) => { + setNumbers(numberList); + setValue(numberList.map(({ value: numberValue }) => numberValue)); + }, + [setValue] + ); + + const onChangeValue = useCallback( + (numberField: { id: string; value: string }) => { + onUpdate( + numbers.map(number => + number.id === numberField.id + ? { + id: numberField.id, + value: parse(numberField.value), + isInvalid: false, + } + : number + ) + ); + }, + [numbers, onUpdate] + ); + + // Add an item to the end of the list + const onAdd = useCallback(() => { + const newArray = [ + ...numbers, + { + id: generateId(), + value: EMPTY_STRING as '', + isInvalid: false, + }, + ]; + onUpdate(newArray); + }, [numbers, onUpdate]); + + const onDelete = useCallback( + (id: string) => onUpdate(numbers.filter(number => number.id !== id)), + [numbers, onUpdate] + ); + + return ( + + <> + {numbers.map((number, arrayIndex) => ( + + + {numbers.length - 1 !== arrayIndex && } + + ))} + + + + + + + + + ); +} + +export { SimpleNumberList }; diff --git a/src/plugins/vis_default_editor/public/components/controls/include_exclude.tsx b/src/plugins/vis_default_editor/public/components/controls/include_exclude.tsx new file mode 100644 index 00000000000000..f60f6ce7ce249b --- /dev/null +++ b/src/plugins/vis_default_editor/public/components/controls/include_exclude.tsx @@ -0,0 +1,49 @@ +/* + * 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, { useEffect } from 'react'; +import { AggParamEditorProps } from '../agg_param_props'; +import { StringParamEditor } from './string'; +import { search } from '../../../../data/public'; +import { SimpleNumberList } from './components/simple_number_list'; +const { isNumberType } = search.aggs; + +export function IncludeExcludeParamEditor(props: AggParamEditorProps>) { + const { agg, value, setValue } = props; + const isAggOfNumberType = isNumberType(agg); + + // This useEffect converts value from string type to number and back when the field type is changed + useEffect(() => { + if (isAggOfNumberType && !Array.isArray(value) && value !== undefined) { + const numberArray = value + .split('|') + .map(item => parseFloat(item)) + .filter(number => Number.isFinite(number)); + setValue(numberArray.length ? numberArray : ['']); + } else if (!isAggOfNumberType && Array.isArray(value) && value !== undefined) { + setValue(value.filter(item => item !== '').join('|')); + } + }, [isAggOfNumberType, setValue, value]); + + return isAggOfNumberType ? ( + } /> + ) : ( + + ); +} diff --git a/src/plugins/vis_default_editor/public/components/controls/index.ts b/src/plugins/vis_default_editor/public/components/controls/index.ts index e8944aa667853f..cfb236e5e22e37 100644 --- a/src/plugins/vis_default_editor/public/components/controls/index.ts +++ b/src/plugins/vis_default_editor/public/components/controls/index.ts @@ -24,6 +24,7 @@ export { ExtendedBoundsParamEditor } from './extended_bounds'; export { FieldParamEditor } from './field'; export { FiltersParamEditor } from './filters'; export { HasExtendedBoundsParamEditor } from './has_extended_bounds'; +export { IncludeExcludeParamEditor } from './include_exclude'; export { IpRangesParamEditor } from './ip_ranges'; export { IpRangeTypeParamEditor } from './ip_range_type'; export { IsFilteredByCollarParamEditor } from './is_filtered_by_collar'; diff --git a/src/plugins/vis_type_table/config.ts b/src/plugins/vis_type_table/config.ts new file mode 100644 index 00000000000000..6749bd83de39f9 --- /dev/null +++ b/src/plugins/vis_type_table/config.ts @@ -0,0 +1,26 @@ +/* + * 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 { schema, TypeOf } from '@kbn/config-schema'; + +export const configSchema = schema.object({ + enabled: schema.boolean({ defaultValue: true }), +}); + +export type ConfigSchema = TypeOf; diff --git a/src/plugins/vis_type_table/kibana.json b/src/plugins/vis_type_table/kibana.json new file mode 100644 index 00000000000000..bb0f6478a42408 --- /dev/null +++ b/src/plugins/vis_type_table/kibana.json @@ -0,0 +1,11 @@ +{ + "id": "visTypeTable", + "version": "kibana", + "server": true, + "ui": true, + "requiredPlugins": [ + "expressions", + "visualizations", + "data" + ] +} diff --git a/src/legacy/core_plugins/vis_type_table/public/__snapshots__/table_vis_fn.test.ts.snap b/src/plugins/vis_type_table/public/__snapshots__/table_vis_fn.test.ts.snap similarity index 100% rename from src/legacy/core_plugins/vis_type_table/public/__snapshots__/table_vis_fn.test.ts.snap rename to src/plugins/vis_type_table/public/__snapshots__/table_vis_fn.test.ts.snap diff --git a/src/legacy/core_plugins/vis_type_table/public/_table_vis.scss b/src/plugins/vis_type_table/public/_table_vis.scss similarity index 100% rename from src/legacy/core_plugins/vis_type_table/public/_table_vis.scss rename to src/plugins/vis_type_table/public/_table_vis.scss diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/_agg_table.scss b/src/plugins/vis_type_table/public/agg_table/_agg_table.scss similarity index 100% rename from src/legacy/core_plugins/vis_type_table/public/agg_table/_agg_table.scss rename to src/plugins/vis_type_table/public/agg_table/_agg_table.scss diff --git a/src/plugins/vis_type_table/public/agg_table/_index.scss b/src/plugins/vis_type_table/public/agg_table/_index.scss new file mode 100644 index 00000000000000..340e08a76f1bdb --- /dev/null +++ b/src/plugins/vis_type_table/public/agg_table/_index.scss @@ -0,0 +1 @@ +@import './agg_table'; diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/agg_table.html b/src/plugins/vis_type_table/public/agg_table/agg_table.html similarity index 100% rename from src/legacy/core_plugins/vis_type_table/public/agg_table/agg_table.html rename to src/plugins/vis_type_table/public/agg_table/agg_table.html diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/agg_table.js b/src/plugins/vis_type_table/public/agg_table/agg_table.js similarity index 98% rename from src/legacy/core_plugins/vis_type_table/public/agg_table/agg_table.js rename to src/plugins/vis_type_table/public/agg_table/agg_table.js index b9e79f96e4fc13..0cd501e2d0344c 100644 --- a/src/legacy/core_plugins/vis_type_table/public/agg_table/agg_table.js +++ b/src/plugins/vis_type_table/public/agg_table/agg_table.js @@ -238,9 +238,9 @@ export function KbnAggTable(config, RecursionHelper) { } /** - * @param {[]Object} columns - the formatted columns that will be displayed + * @param {Object[]} columns - the formatted columns that will be displayed * @param {String} title - the title of the column to add to - * @param {[]Object} rows - the row data for the columns + * @param {Object[]} rows - the row data for the columns * @param {Number} insertAtIndex - the index to insert the percentage column at * @returns {Object} - cols and rows for the table to render now included percentage column(s) */ diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/agg_table_group.html b/src/plugins/vis_type_table/public/agg_table/agg_table_group.html similarity index 100% rename from src/legacy/core_plugins/vis_type_table/public/agg_table/agg_table_group.html rename to src/plugins/vis_type_table/public/agg_table/agg_table_group.html diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/agg_table_group.js b/src/plugins/vis_type_table/public/agg_table/agg_table_group.js similarity index 100% rename from src/legacy/core_plugins/vis_type_table/public/agg_table/agg_table_group.js rename to src/plugins/vis_type_table/public/agg_table/agg_table_group.js diff --git a/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx b/src/plugins/vis_type_table/public/components/table_vis_options.tsx similarity index 96% rename from src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx rename to src/plugins/vis_type_table/public/components/table_vis_options.tsx index 265528f33f9cd0..68348d5ef10604 100644 --- a/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx +++ b/src/plugins/vis_type_table/public/components/table_vis_options.tsx @@ -24,12 +24,8 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; -import { search } from '../../../../../plugins/data/public'; -import { - SwitchOption, - SelectOption, - NumberInputOption, -} from '../../../../../plugins/charts/public'; +import { search } from '../../../data/public'; +import { SwitchOption, SelectOption, NumberInputOption } from '../../../charts/public'; import { TableVisParams } from '../types'; import { totalAggregations } from './utils'; diff --git a/src/legacy/core_plugins/vis_type_table/public/components/utils.ts b/src/plugins/vis_type_table/public/components/utils.ts similarity index 100% rename from src/legacy/core_plugins/vis_type_table/public/components/utils.ts rename to src/plugins/vis_type_table/public/components/utils.ts diff --git a/src/legacy/core_plugins/vis_type_table/public/get_inner_angular.ts b/src/plugins/vis_type_table/public/get_inner_angular.ts similarity index 91% rename from src/legacy/core_plugins/vis_type_table/public/get_inner_angular.ts rename to src/plugins/vis_type_table/public/get_inner_angular.ts index 6208e358b4184f..d69b9bba31b032 100644 --- a/src/legacy/core_plugins/vis_type_table/public/get_inner_angular.ts +++ b/src/plugins/vis_type_table/public/get_inner_angular.ts @@ -23,7 +23,7 @@ import angular from 'angular'; import 'angular-recursion'; import { i18nDirective, i18nFilter, I18nProvider } from '@kbn/i18n/angular'; -import { CoreStart, LegacyCoreStart, IUiSettingsClient } from 'kibana/public'; +import { CoreStart, IUiSettingsClient, PluginInitializerContext } from 'kibana/public'; import { initAngularBootstrap, PaginateDirectiveProvider, @@ -32,15 +32,15 @@ import { watchMultiDecorator, KbnAccessibleClickProvider, configureAppAngularModule, -} from '../../../../plugins/kibana_legacy/public'; +} from '../../kibana_legacy/public'; initAngularBootstrap(); const thirdPartyAngularDependencies = ['ngSanitize', 'ui.bootstrap', 'RecursionHelper']; -export function getAngularModule(name: string, core: CoreStart) { +export function getAngularModule(name: string, core: CoreStart, context: PluginInitializerContext) { const uiModule = getInnerAngular(name, core); - configureAppAngularModule(uiModule, core as LegacyCoreStart, true); + configureAppAngularModule(uiModule, { core, env: context.env }, true); return uiModule; } diff --git a/src/legacy/core_plugins/vis_type_table/public/index.scss b/src/plugins/vis_type_table/public/index.scss similarity index 61% rename from src/legacy/core_plugins/vis_type_table/public/index.scss rename to src/plugins/vis_type_table/public/index.scss index 54124ebc42620b..0972c85e0dbe03 100644 --- a/src/legacy/core_plugins/vis_type_table/public/index.scss +++ b/src/plugins/vis_type_table/public/index.scss @@ -1,5 +1,3 @@ -@import 'src/legacy/ui/public/styles/styling_constants'; - // Prefix all styles with "tbv" to avoid conflicts. // Examples // tbvChart @@ -7,6 +5,6 @@ // tbvChart__legend--small // tbvChart__legend-isLoading -@import 'agg_table/index'; -@import 'paginated_table/index'; +@import './agg_table/index'; +@import './paginated_table/index'; @import './table_vis'; diff --git a/src/legacy/core_plugins/vis_type_table/public/index.ts b/src/plugins/vis_type_table/public/index.ts similarity index 92% rename from src/legacy/core_plugins/vis_type_table/public/index.ts rename to src/plugins/vis_type_table/public/index.ts index efbaf69659ea29..5621fdb0947724 100644 --- a/src/legacy/core_plugins/vis_type_table/public/index.ts +++ b/src/plugins/vis_type_table/public/index.ts @@ -16,8 +16,8 @@ * specific language governing permissions and limitations * under the License. */ - -import { PluginInitializerContext } from '../../../../core/public'; +import './index.scss'; +import { PluginInitializerContext } from 'kibana/public'; import { TableVisPlugin as Plugin } from './plugin'; export function plugin(initializerContext: PluginInitializerContext) { diff --git a/src/plugins/vis_type_table/public/paginated_table/_index.scss b/src/plugins/vis_type_table/public/paginated_table/_index.scss new file mode 100644 index 00000000000000..23d56c09b2818a --- /dev/null +++ b/src/plugins/vis_type_table/public/paginated_table/_index.scss @@ -0,0 +1 @@ +@import './_table_cell_filter'; diff --git a/src/legacy/core_plugins/vis_type_table/public/paginated_table/_table_cell_filter.scss b/src/plugins/vis_type_table/public/paginated_table/_table_cell_filter.scss similarity index 100% rename from src/legacy/core_plugins/vis_type_table/public/paginated_table/_table_cell_filter.scss rename to src/plugins/vis_type_table/public/paginated_table/_table_cell_filter.scss diff --git a/src/legacy/core_plugins/vis_type_table/public/paginated_table/paginated_table.html b/src/plugins/vis_type_table/public/paginated_table/paginated_table.html similarity index 100% rename from src/legacy/core_plugins/vis_type_table/public/paginated_table/paginated_table.html rename to src/plugins/vis_type_table/public/paginated_table/paginated_table.html diff --git a/src/legacy/core_plugins/vis_type_table/public/paginated_table/paginated_table.js b/src/plugins/vis_type_table/public/paginated_table/paginated_table.js similarity index 100% rename from src/legacy/core_plugins/vis_type_table/public/paginated_table/paginated_table.js rename to src/plugins/vis_type_table/public/paginated_table/paginated_table.js diff --git a/src/legacy/core_plugins/vis_type_table/public/paginated_table/paginated_table.test.ts b/src/plugins/vis_type_table/public/paginated_table/paginated_table.test.ts similarity index 98% rename from src/legacy/core_plugins/vis_type_table/public/paginated_table/paginated_table.test.ts rename to src/plugins/vis_type_table/public/paginated_table/paginated_table.test.ts index 7352236f03febf..23e4aee0378dc6 100644 --- a/src/legacy/core_plugins/vis_type_table/public/paginated_table/paginated_table.test.ts +++ b/src/plugins/vis_type_table/public/paginated_table/paginated_table.test.ts @@ -25,10 +25,9 @@ import 'angular-mocks'; import { getAngularModule } from '../get_inner_angular'; import { initTableVisLegacyModule } from '../table_vis_legacy_module'; -import { coreMock } from '../../../../../core/public/mocks'; +import { coreMock } from '../../../../core/public/mocks'; -jest.mock('ui/new_platform'); -jest.mock('../../../../../plugins/kibana_legacy/public/angular/angular_config', () => ({ +jest.mock('../../../kibana_legacy/public/angular/angular_config', () => ({ configureAppAngularModule: () => {}, })); @@ -73,7 +72,11 @@ describe('Table Vis - Paginated table', () => { let paginatedTable: any; const initLocalAngular = () => { - const tableVisModule = getAngularModule('kibana/table_vis', coreMock.createStart()); + const tableVisModule = getAngularModule( + 'kibana/table_vis', + coreMock.createStart(), + coreMock.createPluginInitializerContext() + ); initTableVisLegacyModule(tableVisModule); }; diff --git a/src/legacy/core_plugins/vis_type_table/public/paginated_table/rows.js b/src/plugins/vis_type_table/public/paginated_table/rows.js similarity index 100% rename from src/legacy/core_plugins/vis_type_table/public/paginated_table/rows.js rename to src/plugins/vis_type_table/public/paginated_table/rows.js diff --git a/src/legacy/core_plugins/vis_type_table/public/paginated_table/table_cell_filter.html b/src/plugins/vis_type_table/public/paginated_table/table_cell_filter.html similarity index 100% rename from src/legacy/core_plugins/vis_type_table/public/paginated_table/table_cell_filter.html rename to src/plugins/vis_type_table/public/paginated_table/table_cell_filter.html diff --git a/src/legacy/core_plugins/vis_type_table/public/plugin.ts b/src/plugins/vis_type_table/public/plugin.ts similarity index 80% rename from src/legacy/core_plugins/vis_type_table/public/plugin.ts rename to src/plugins/vis_type_table/public/plugin.ts index ea12a5320a14d4..a41d939523bcca 100644 --- a/src/legacy/core_plugins/vis_type_table/public/plugin.ts +++ b/src/plugins/vis_type_table/public/plugin.ts @@ -16,14 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -import { Plugin as ExpressionsPublicPlugin } from '../../../../plugins/expressions/public'; -import { VisualizationsSetup } from '../../../../plugins/visualizations/public'; - -import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '../../../../core/public'; +import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'kibana/public'; +import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public'; +import { VisualizationsSetup } from '../../visualizations/public'; import { createTableVisFn } from './table_vis_fn'; -import { tableVisTypeDefinition } from './table_vis_type'; -import { DataPublicPluginStart } from '../../../../plugins/data/public'; +import { getTableVisTypeDefinition } from './table_vis_type'; +import { DataPublicPluginStart } from '../../data/public'; import { setFormatService } from './services'; /** @internal */ @@ -40,6 +39,7 @@ export interface TablePluginStartDependencies { /** @internal */ export class TableVisPlugin implements Plugin, void> { initializerContext: PluginInitializerContext; + createBaseVisualization: any; constructor(initializerContext: PluginInitializerContext) { this.initializerContext = initializerContext; @@ -50,8 +50,9 @@ export class TableVisPlugin implements Plugin, void> { { expressions, visualizations }: TablePluginSetupDependencies ) { expressions.registerFunction(createTableVisFn); - - visualizations.createBaseVisualization(tableVisTypeDefinition); + visualizations.createBaseVisualization( + getTableVisTypeDefinition(core, this.initializerContext) + ); } public start(core: CoreStart, { data }: TablePluginStartDependencies) { diff --git a/src/legacy/core_plugins/vis_type_table/public/services.ts b/src/plugins/vis_type_table/public/services.ts similarity index 86% rename from src/legacy/core_plugins/vis_type_table/public/services.ts rename to src/plugins/vis_type_table/public/services.ts index b4b491ac7a5552..3aaffe75e27f14 100644 --- a/src/legacy/core_plugins/vis_type_table/public/services.ts +++ b/src/plugins/vis_type_table/public/services.ts @@ -17,8 +17,8 @@ * under the License. */ -import { createGetterSetter } from '../../../../plugins/kibana_utils/public'; -import { DataPublicPluginStart } from '../../../../plugins/data/public'; +import { createGetterSetter } from '../../kibana_utils/public'; +import { DataPublicPluginStart } from '../../data/public'; export const [getFormatService, setFormatService] = createGetterSetter< DataPublicPluginStart['fieldFormats'] diff --git a/src/legacy/core_plugins/vis_type_table/public/table_vis.html b/src/plugins/vis_type_table/public/table_vis.html similarity index 100% rename from src/legacy/core_plugins/vis_type_table/public/table_vis.html rename to src/plugins/vis_type_table/public/table_vis.html diff --git a/src/legacy/core_plugins/vis_type_table/public/table_vis_controller.js b/src/plugins/vis_type_table/public/table_vis_controller.js similarity index 100% rename from src/legacy/core_plugins/vis_type_table/public/table_vis_controller.js rename to src/plugins/vis_type_table/public/table_vis_controller.js diff --git a/src/legacy/core_plugins/vis_type_table/public/table_vis_controller.test.ts b/src/plugins/vis_type_table/public/table_vis_controller.test.ts similarity index 89% rename from src/legacy/core_plugins/vis_type_table/public/table_vis_controller.test.ts rename to src/plugins/vis_type_table/public/table_vis_controller.test.ts index 8d6f88bf8dd4af..4607324ca150c6 100644 --- a/src/legacy/core_plugins/vis_type_table/public/table_vis_controller.test.ts +++ b/src/plugins/vis_type_table/public/table_vis_controller.test.ts @@ -26,24 +26,23 @@ import $ from 'jquery'; import StubIndexPattern from 'test_utils/stub_index_pattern'; import { getAngularModule } from './get_inner_angular'; import { initTableVisLegacyModule } from './table_vis_legacy_module'; -import { tableVisTypeDefinition } from './table_vis_type'; -import { Vis } from '../../../../plugins/visualizations/public'; +import { getTableVisTypeDefinition } from './table_vis_type'; +import { Vis } from '../../visualizations/public'; // eslint-disable-next-line -import { stubFields } from '../../../../plugins/data/public/stubs'; +import { stubFields } from '../../data/public/stubs'; // eslint-disable-next-line import { tableVisResponseHandler } from './table_vis_response_handler'; -import { coreMock } from '../../../../core/public/mocks'; +import { coreMock } from '../../../core/public/mocks'; +import { IAggConfig, search } from '../../data/public'; +// TODO: remove linting disable // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { npStart } from './legacy_imports'; -import { IAggConfig, search } from '../../../../plugins/data/public'; +import { searchStartMock } from '../../data/public/search/mocks'; -// should be mocked once get rid of 'ui/new_platform' legacy imports -const { createAggConfigs } = npStart.plugins.data.search.aggs; +const { createAggConfigs } = searchStartMock.aggs; const { tabifyAggResponse } = search; -jest.mock('ui/new_platform'); -jest.mock('../../../../plugins/kibana_legacy/public/angular/angular_config', () => ({ +jest.mock('../../kibana_legacy/public/angular/angular_config', () => ({ configureAppAngularModule: () => {}, })); @@ -89,7 +88,11 @@ describe('Table Vis - Controller', () => { let stubIndexPattern: any; const initLocalAngular = () => { - const tableVisModule = getAngularModule('kibana/table_vis', coreMock.createStart()); + const tableVisModule = getAngularModule( + 'kibana/table_vis', + coreMock.createStart(), + coreMock.createPluginInitializerContext() + ); initTableVisLegacyModule(tableVisModule); }; @@ -110,9 +113,13 @@ describe('Table Vis - Controller', () => { (cfg: any) => cfg, 'time', stubFields, - coreMock.createStart() + coreMock.createSetup() ); }); + const tableVisTypeDefinition = getTableVisTypeDefinition( + coreMock.createSetup(), + coreMock.createPluginInitializerContext() + ); function getRangeVis(params?: object) { return ({ diff --git a/src/legacy/core_plugins/vis_type_table/public/table_vis_fn.test.ts b/src/plugins/vis_type_table/public/table_vis_fn.test.ts similarity index 95% rename from src/legacy/core_plugins/vis_type_table/public/table_vis_fn.test.ts rename to src/plugins/vis_type_table/public/table_vis_fn.test.ts index 36392c10f93f32..9accf8950d910b 100644 --- a/src/legacy/core_plugins/vis_type_table/public/table_vis_fn.test.ts +++ b/src/plugins/vis_type_table/public/table_vis_fn.test.ts @@ -21,7 +21,7 @@ import { createTableVisFn } from './table_vis_fn'; import { tableVisResponseHandler } from './table_vis_response_handler'; // eslint-disable-next-line -import { functionWrapper } from '../../../../plugins/expressions/common/expression_functions/specs/tests/utils'; +import { functionWrapper } from '../../expressions/common/expression_functions/specs/tests/utils'; jest.mock('./table_vis_response_handler', () => ({ tableVisResponseHandler: jest.fn().mockReturnValue({ diff --git a/src/legacy/core_plugins/vis_type_table/public/table_vis_fn.ts b/src/plugins/vis_type_table/public/table_vis_fn.ts similarity index 94% rename from src/legacy/core_plugins/vis_type_table/public/table_vis_fn.ts rename to src/plugins/vis_type_table/public/table_vis_fn.ts index a97e596e89754c..9739a7a284e6cf 100644 --- a/src/legacy/core_plugins/vis_type_table/public/table_vis_fn.ts +++ b/src/plugins/vis_type_table/public/table_vis_fn.ts @@ -19,11 +19,7 @@ import { i18n } from '@kbn/i18n'; import { tableVisResponseHandler, TableContext } from './table_vis_response_handler'; -import { - ExpressionFunctionDefinition, - KibanaDatatable, - Render, -} from '../../../../plugins/expressions/public'; +import { ExpressionFunctionDefinition, KibanaDatatable, Render } from '../../expressions/public'; export type Input = KibanaDatatable; diff --git a/src/legacy/core_plugins/vis_type_table/public/table_vis_legacy_module.ts b/src/plugins/vis_type_table/public/table_vis_legacy_module.ts similarity index 100% rename from src/legacy/core_plugins/vis_type_table/public/table_vis_legacy_module.ts rename to src/plugins/vis_type_table/public/table_vis_legacy_module.ts diff --git a/src/legacy/core_plugins/vis_type_table/public/table_vis_response_handler.ts b/src/plugins/vis_type_table/public/table_vis_response_handler.ts similarity index 100% rename from src/legacy/core_plugins/vis_type_table/public/table_vis_response_handler.ts rename to src/plugins/vis_type_table/public/table_vis_response_handler.ts diff --git a/src/plugins/vis_type_table/public/table_vis_type.ts b/src/plugins/vis_type_table/public/table_vis_type.ts new file mode 100644 index 00000000000000..26e5ac8cfd71ab --- /dev/null +++ b/src/plugins/vis_type_table/public/table_vis_type.ts @@ -0,0 +1,100 @@ +/* + * 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 } from 'kibana/public'; +import { i18n } from '@kbn/i18n'; +import { AggGroupNames } from '../../data/public'; +import { Schemas } from '../../vis_default_editor/public'; +import { Vis } from '../../visualizations/public'; +import { tableVisResponseHandler } from './table_vis_response_handler'; +// @ts-ignore +import tableVisTemplate from './table_vis.html'; +import { TableOptions } from './components/table_vis_options'; +import { getTableVisualizationControllerClass } from './vis_controller'; + +export function getTableVisTypeDefinition(core: CoreSetup, context: PluginInitializerContext) { + return { + type: 'table', + name: 'table', + title: i18n.translate('visTypeTable.tableVisTitle', { + defaultMessage: 'Data Table', + }), + icon: 'visTable', + description: i18n.translate('visTypeTable.tableVisDescription', { + defaultMessage: 'Display values in a table', + }), + visualization: getTableVisualizationControllerClass(core, context), + visConfig: { + defaults: { + perPage: 10, + showPartialRows: false, + showMetricsAtAllLevels: false, + sort: { + columnIndex: null, + direction: null, + }, + showTotal: false, + totalFunc: 'sum', + percentageCol: '', + }, + template: tableVisTemplate, + }, + editorConfig: { + optionsTemplate: TableOptions, + schemas: new Schemas([ + { + group: AggGroupNames.Metrics, + name: 'metric', + title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.metricTitle', { + defaultMessage: 'Metric', + }), + aggFilter: ['!geo_centroid', '!geo_bounds'], + aggSettings: { + top_hits: { + allowStrings: true, + }, + }, + min: 1, + defaults: [{ type: 'count', schema: 'metric' }], + }, + { + group: AggGroupNames.Buckets, + name: 'bucket', + title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.bucketTitle', { + defaultMessage: 'Split rows', + }), + aggFilter: ['!filter'], + }, + { + group: AggGroupNames.Buckets, + name: 'split', + title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.splitTitle', { + defaultMessage: 'Split table', + }), + min: 0, + max: 1, + aggFilter: ['!filter'], + }, + ]), + }, + responseHandler: tableVisResponseHandler, + hierarchicalData: (vis: Vis) => { + return Boolean(vis.params.showPartialRows || vis.params.showMetricsAtAllLevels); + }, + }; +} diff --git a/src/legacy/core_plugins/vis_type_table/public/types.ts b/src/plugins/vis_type_table/public/types.ts similarity index 94% rename from src/legacy/core_plugins/vis_type_table/public/types.ts rename to src/plugins/vis_type_table/public/types.ts index c6de14b9f050c6..39023d1305cb63 100644 --- a/src/legacy/core_plugins/vis_type_table/public/types.ts +++ b/src/plugins/vis_type_table/public/types.ts @@ -17,7 +17,7 @@ * under the License. */ -import { SchemaConfig } from '../../../../plugins/visualizations/public'; +import { SchemaConfig } from '../../visualizations/public'; export enum AggTypes { SUM = 'sum', diff --git a/src/plugins/vis_type_table/public/vis_controller.ts b/src/plugins/vis_type_table/public/vis_controller.ts new file mode 100644 index 00000000000000..d49dd32c8c89c3 --- /dev/null +++ b/src/plugins/vis_type_table/public/vis_controller.ts @@ -0,0 +1,109 @@ +/* + * 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 } from 'kibana/public'; +import angular, { IModule, auto, IRootScopeService, IScope, ICompileService } from 'angular'; +import $ from 'jquery'; + +import { VisParams, ExprVis } from '../../visualizations/public'; +import { getAngularModule } from './get_inner_angular'; +import { initTableVisLegacyModule } from './table_vis_legacy_module'; + +const innerAngularName = 'kibana/table_vis'; + +export function getTableVisualizationControllerClass( + core: CoreSetup, + context: PluginInitializerContext +) { + return class TableVisualizationController { + private tableVisModule: IModule | undefined; + private injector: auto.IInjectorService | undefined; + el: JQuery; + vis: ExprVis; + $rootScope: IRootScopeService | null = null; + $scope: (IScope & { [key: string]: any }) | undefined; + $compile: ICompileService | undefined; + + constructor(domeElement: Element, vis: ExprVis) { + this.el = $(domeElement); + this.vis = vis; + } + + getInjector() { + if (!this.injector) { + const mountpoint = document.createElement('div'); + mountpoint.setAttribute('style', 'height: 100%; width: 100%;'); + this.injector = angular.bootstrap(mountpoint, [innerAngularName]); + this.el.append(mountpoint); + } + + return this.injector; + } + + async initLocalAngular() { + if (!this.tableVisModule) { + const [coreStart] = await core.getStartServices(); + this.tableVisModule = getAngularModule(innerAngularName, coreStart, context); + initTableVisLegacyModule(this.tableVisModule); + } + } + + async render(esResponse: object, visParams: VisParams) { + await this.initLocalAngular(); + + return new Promise(async (resolve, reject) => { + if (!this.$rootScope) { + const $injector = this.getInjector(); + this.$rootScope = $injector.get('$rootScope'); + this.$compile = $injector.get('$compile'); + } + const updateScope = () => { + if (!this.$scope) { + return; + } + this.$scope.vis = this.vis; + this.$scope.visState = { params: visParams }; + this.$scope.esResponse = esResponse; + + this.$scope.visParams = visParams; + this.$scope.renderComplete = resolve; + this.$scope.renderFailed = reject; + this.$scope.resize = Date.now(); + this.$scope.$apply(); + }; + + if (!this.$scope && this.$compile) { + 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.$scope.$apply(); + } else { + updateScope(); + } + }); + } + + destroy() { + if (this.$rootScope) { + this.$rootScope.$destroy(); + this.$rootScope = null; + } + } + }; +} diff --git a/src/plugins/vis_type_table/server/index.ts b/src/plugins/vis_type_table/server/index.ts new file mode 100644 index 00000000000000..882958a28777d1 --- /dev/null +++ b/src/plugins/vis_type_table/server/index.ts @@ -0,0 +1,34 @@ +/* + * 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 { PluginConfigDescriptor } from 'kibana/server'; + +import { configSchema, ConfigSchema } from '../config'; + +export const config: PluginConfigDescriptor = { + schema: configSchema, + deprecations: ({ renameFromRoot }) => [ + renameFromRoot('table_vis.enabled', 'vis_type_table.enabled'), + ], +}; + +export const plugin = () => ({ + setup() {}, + start() {}, +}); diff --git a/src/plugins/vis_type_timeseries/kibana.json b/src/plugins/vis_type_timeseries/kibana.json index 38662c6a7ff89b..9053d2543e0d0e 100644 --- a/src/plugins/vis_type_timeseries/kibana.json +++ b/src/plugins/vis_type_timeseries/kibana.json @@ -4,6 +4,6 @@ "kibanaVersion": "kibana", "server": true, "ui": true, - "requiredPlugins": ["data", "expressions", "visualizations"], + "requiredPlugins": ["charts", "data", "expressions", "visualizations"], "optionalPlugins": ["usageCollection"] } diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/config.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/config.js index 024f59c3abb1c3..d29b795b10ec83 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/config.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/config.js @@ -53,7 +53,7 @@ export const TimeseriesConfig = injectI18n(function(props) { point_size: '', value_template: '{{value}}', offset_time: '', - split_color_mode: 'gradient', + split_color_mode: 'kibana', axis_min: '', axis_max: '', stacked: STACKED_OPTIONS.NONE, @@ -140,10 +140,10 @@ export const TimeseriesConfig = injectI18n(function(props) { const splitColorOptions = [ { label: intl.formatMessage({ - id: 'visTypeTimeseries.timeSeries.gradientLabel', - defaultMessage: 'Gradient', + id: 'visTypeTimeseries.timeSeries.defaultPaletteLabel', + defaultMessage: 'Default palette', }), - value: 'gradient', + value: 'kibana', }, { label: intl.formatMessage({ @@ -152,6 +152,13 @@ export const TimeseriesConfig = injectI18n(function(props) { }), value: 'rainbow', }, + { + label: intl.formatMessage({ + id: 'visTypeTimeseries.timeSeries.gradientLabel', + defaultMessage: 'Gradient', + }), + value: 'gradient', + }, ]; const selectedSplitColorOption = splitColorOptions.find(option => { return model.split_color_mode === option.value; diff --git a/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js index b1c3c7ac6b67ad..5cf1619150e5c7 100644 --- a/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js +++ b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js @@ -33,7 +33,7 @@ import { import { EuiIcon } from '@elastic/eui'; import { getTimezone } from '../../../lib/get_timezone'; import { eventBus, ACTIVE_CURSOR } from '../../lib/active_cursor'; -import { getUISettings } from '../../../../services'; +import { getUISettings, getChartsSetup } from '../../../../services'; import { GRID_LINE_CONFIG, ICON_TYPES_MAP, STACKED_OPTIONS } from '../../constants'; import { AreaSeriesDecorator } from './decorators/area_decorator'; import { BarSeriesDecorator } from './decorators/bar_decorator'; @@ -94,6 +94,12 @@ export const TimeSeries = ({ // apply legend style change if bgColor is configured const classes = classNames('tvbVisTimeSeries', getChartClasses(backgroundColor)); + // If the color isn't configured by the user, use the color mapping service + // to assign a color from the Kibana palette. Colors will be shared across the + // session, including dashboards. + const { colors } = getChartsSetup(); + colors.mappedColors.mapKeys(series.filter(({ color }) => !color).map(({ label }) => label)); + return ( ; visualizations: VisualizationsSetup; + charts: ChartsPluginSetup; } /** @internal */ @@ -56,10 +59,11 @@ export class MetricsPlugin implements Plugin, void> { public async setup( core: CoreSetup, - { expressions, visualizations }: MetricsPluginSetupDependencies + { expressions, visualizations, charts }: MetricsPluginSetupDependencies ) { expressions.registerFunction(createMetricsFn); setUISettings(core.uiSettings); + setChartsSetup(charts); visualizations.createReactVisualization(metricsVisDefinition); } diff --git a/src/plugins/vis_type_timeseries/public/services.ts b/src/plugins/vis_type_timeseries/public/services.ts index d93a376584eac9..9aa84478fb78bf 100644 --- a/src/plugins/vis_type_timeseries/public/services.ts +++ b/src/plugins/vis_type_timeseries/public/services.ts @@ -19,6 +19,7 @@ import { I18nStart, SavedObjectsStart, IUiSettingsClient, CoreStart } from 'src/core/public'; import { createGetterSetter } from '../../kibana_utils/public'; +import { ChartsPluginSetup } from '../../charts/public'; import { DataPublicPluginStart } from '../../data/public'; export const [getUISettings, setUISettings] = createGetterSetter('UISettings'); @@ -36,3 +37,7 @@ export const [getCoreStart, setCoreStart] = createGetterSetter('CoreS export const [getDataStart, setDataStart] = createGetterSetter('DataStart'); export const [getI18n, setI18n] = createGetterSetter('I18n'); + +export const [getChartsSetup, setChartsSetup] = createGetterSetter( + 'ChartsPluginSetup' +); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_split_colors.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_split_colors.js index ff8d9077b08711..cad8c8f2025a17 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_split_colors.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_split_colors.js @@ -19,7 +19,7 @@ import Color from 'color'; -export function getSplitColors(inputColor, size = 10, style = 'gradient') { +export function getSplitColors(inputColor, size = 10, style = 'kibana') { const color = new Color(inputColor); const colors = []; let workingColor = Color.hsl(color.hsl().object()); @@ -49,7 +49,7 @@ export function getSplitColors(inputColor, size = 10, style = 'gradient') { '#0F1419', '#666666', ]; - } else { + } else if (style === 'gradient') { colors.push(color.string()); const rotateBy = color.luminosity() / (size - 1); for (let i = 0; i < size - 1; i++) { diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_splits.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_splits.test.js index 0874d944033f5c..376d32d0da13f6 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_splits.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_splits.test.js @@ -106,7 +106,7 @@ describe('getSplits(resp, panel, series)', () => { ]); }); - test('should return a splits for terms group bys', () => { + describe('terms group bys', () => { const resp = { aggregations: { SERIES: { @@ -126,38 +126,89 @@ describe('getSplits(resp, panel, series)', () => { }, }, }; - const series = { - id: 'SERIES', - color: '#F00', - split_mode: 'terms', - terms_field: 'beat.hostname', - terms_size: 10, - metrics: [ - { id: 'AVG', type: 'avg', field: 'cpu' }, - { id: 'SIBAGG', type: 'avg_bucket', field: 'AVG' }, - ], - }; - const panel = { type: 'timeseries' }; - expect(getSplits(resp, panel, series)).toEqual([ - { - id: 'SERIES:example-01', - key: 'example-01', - label: 'example-01', - meta: { bucketSize: 10 }, - color: 'rgb(255, 0, 0)', - timeseries: { buckets: [] }, - SIBAGG: { value: 1 }, - }, - { - id: 'SERIES:example-02', - key: 'example-02', - label: 'example-02', - meta: { bucketSize: 10 }, - color: 'rgb(147, 0, 0)', - timeseries: { buckets: [] }, - SIBAGG: { value: 2 }, - }, - ]); + + test('should return a splits with no color', () => { + const series = { + id: 'SERIES', + color: '#F00', + split_mode: 'terms', + terms_field: 'beat.hostname', + terms_size: 10, + metrics: [ + { id: 'AVG', type: 'avg', field: 'cpu' }, + { id: 'SIBAGG', type: 'avg_bucket', field: 'AVG' }, + ], + }; + const panel = { type: 'timeseries' }; + expect(getSplits(resp, panel, series)).toEqual([ + { + id: 'SERIES:example-01', + key: 'example-01', + label: 'example-01', + meta: { bucketSize: 10 }, + color: undefined, + timeseries: { buckets: [] }, + SIBAGG: { value: 1 }, + }, + { + id: 'SERIES:example-02', + key: 'example-02', + label: 'example-02', + meta: { bucketSize: 10 }, + color: undefined, + timeseries: { buckets: [] }, + SIBAGG: { value: 2 }, + }, + ]); + }); + + test('should return gradient color', () => { + const series = { + id: 'SERIES', + color: '#F00', + split_mode: 'terms', + split_color_mode: 'gradient', + terms_field: 'beat.hostname', + terms_size: 10, + metrics: [ + { id: 'AVG', type: 'avg', field: 'cpu' }, + { id: 'SIBAGG', type: 'avg_bucket', field: 'AVG' }, + ], + }; + const panel = { type: 'timeseries' }; + expect(getSplits(resp, panel, series)).toEqual([ + expect.objectContaining({ + color: 'rgb(255, 0, 0)', + }), + expect.objectContaining({ + color: 'rgb(147, 0, 0)', + }), + ]); + }); + + test('should return rainbow color', () => { + const series = { + id: 'SERIES', + color: '#F00', + split_mode: 'terms', + split_color_mode: 'rainbow', + terms_field: 'beat.hostname', + terms_size: 10, + metrics: [ + { id: 'AVG', type: 'avg', field: 'cpu' }, + { id: 'SIBAGG', type: 'avg_bucket', field: 'AVG' }, + ], + }; + const panel = { type: 'timeseries' }; + expect(getSplits(resp, panel, series)).toEqual([ + expect.objectContaining({ + color: '#68BC00', + }), + expect.objectContaining({ + color: '#009CE0', + }), + ]); + }); }); test('should return a splits for filters group bys', () => { diff --git a/src/legacy/core_plugins/vis_type_table/public/legacy_imports.ts b/src/plugins/vis_type_timeseries/server/saved_objects/index.ts similarity index 92% rename from src/legacy/core_plugins/vis_type_table/public/legacy_imports.ts rename to src/plugins/vis_type_timeseries/server/saved_objects/index.ts index 1030e971d64504..5f7f5767f423de 100644 --- a/src/legacy/core_plugins/vis_type_table/public/legacy_imports.ts +++ b/src/plugins/vis_type_timeseries/server/saved_objects/index.ts @@ -17,4 +17,4 @@ * under the License. */ -export { npSetup, npStart } from 'ui/new_platform'; +export { tsvbTelemetrySavedObjectType } from './tsvb_telemetry'; diff --git a/src/plugins/vis_type_timeseries/server/validation_telemetry/saved_object_type.ts b/src/plugins/vis_type_timeseries/server/saved_objects/tsvb_telemetry.ts similarity index 100% rename from src/plugins/vis_type_timeseries/server/validation_telemetry/saved_object_type.ts rename to src/plugins/vis_type_timeseries/server/saved_objects/tsvb_telemetry.ts diff --git a/src/plugins/vis_type_timeseries/server/validation_telemetry/validation_telemetry_service.ts b/src/plugins/vis_type_timeseries/server/validation_telemetry/validation_telemetry_service.ts index 779d9441df2fd9..e4b8ca19094e48 100644 --- a/src/plugins/vis_type_timeseries/server/validation_telemetry/validation_telemetry_service.ts +++ b/src/plugins/vis_type_timeseries/server/validation_telemetry/validation_telemetry_service.ts @@ -19,7 +19,7 @@ import { APICaller, CoreSetup, Plugin, PluginInitializerContext } from 'kibana/server'; import { UsageCollectionSetup } from '../../../usage_collection/server'; -import { tsvbTelemetrySavedObjectType } from './saved_object_type'; +import { tsvbTelemetrySavedObjectType } from '../saved_objects'; export interface ValidationTelemetryServiceSetup { logFailedValidation: () => void; diff --git a/src/plugins/visualizations/kibana.json b/src/plugins/visualizations/kibana.json index cd22b1375ae1b7..f3f9cbd8341ecf 100644 --- a/src/plugins/visualizations/kibana.json +++ b/src/plugins/visualizations/kibana.json @@ -3,5 +3,5 @@ "version": "kibana", "server": true, "ui": true, - "requiredPlugins": ["data", "expressions", "uiActions", "embeddable", "usageCollection"] + "requiredPlugins": ["data", "expressions", "uiActions", "embeddable", "usageCollection", "inspector"] } diff --git a/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts b/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts index bf2d174f594b2f..8e51bd4ac5d4fa 100644 --- a/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts +++ b/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts @@ -28,8 +28,9 @@ import { getTimeFilter, getCapabilities, } from '../services'; +import { VisualizeEmbeddableFactoryDeps } from './visualize_embeddable_factory'; -export const createVisEmbeddableFromObject = async ( +export const createVisEmbeddableFromObject = (deps: VisualizeEmbeddableFactoryDeps) => async ( vis: Vis, input: Partial & { id: string }, parent?: IContainer @@ -58,6 +59,7 @@ export const createVisEmbeddableFromObject = async ( indexPatterns, editUrl, editable, + deps, }, input, parent diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts index e64d2002517977..ffb028ff131b39 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts @@ -42,6 +42,7 @@ import { buildPipeline } from '../legacy/build_pipeline'; import { Vis } from '../vis'; import { getExpressions, getUiActions } from '../services'; import { VIS_EVENT_TO_TRIGGER } from './events'; +import { VisualizeEmbeddableFactoryDeps } from './visualize_embeddable_factory'; const getKeys = (o: T): Array => Object.keys(o) as Array; @@ -50,6 +51,7 @@ export interface VisualizeEmbeddableConfiguration { indexPatterns?: IIndexPattern[]; editUrl: string; editable: boolean; + deps: VisualizeEmbeddableFactoryDeps; } export interface VisualizeInput extends EmbeddableInput { @@ -84,10 +86,11 @@ export class VisualizeEmbeddable extends Embeddable { - if (this.handler) { - return this.handler.openInspector(this.getTitle() || ''); - } + if (!this.handler) return; + + const adapters = this.handler.inspect(); + if (!adapters) return; + + this.deps.start().plugins.inspector.open(adapters, { + title: this.getTitle() || '', + }); }; /** diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx b/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx index 4b7d01ae3b2466..6ab1c98645988f 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx @@ -25,7 +25,7 @@ import { EmbeddableOutput, ErrorEmbeddable, IContainer, -} from '../../../../plugins/embeddable/public'; +} from '../../../embeddable/public'; import { DisabledLabEmbeddable } from './disabled_lab_embeddable'; import { VisualizeEmbeddable, VisualizeInput, VisualizeOutput } from './visualize_embeddable'; import { VISUALIZE_EMBEDDABLE_TYPE } from './constants'; @@ -39,11 +39,17 @@ import { import { showNewVisModal } from '../wizard'; import { convertToSerializedVis } from '../saved_visualizations/_saved_vis'; import { createVisEmbeddableFromObject } from './create_vis_embeddable_from_object'; +import { StartServicesGetter } from '../../../kibana_utils/public'; +import { VisualizationsStartDeps } from '../plugin'; interface VisualizationAttributes extends SavedObjectAttributes { visState: string; } +export interface VisualizeEmbeddableFactoryDeps { + start: StartServicesGetter>; +} + export class VisualizeEmbeddableFactory implements EmbeddableFactoryDefinition< @@ -79,7 +85,8 @@ export class VisualizeEmbeddableFactory return visType.stage !== 'experimental'; }, }; - constructor() {} + + constructor(private readonly deps: VisualizeEmbeddableFactoryDeps) {} public async isEditable() { return getCapabilities().visualize.save as boolean; @@ -101,7 +108,7 @@ export class VisualizeEmbeddableFactory try { const savedObject = await savedVisualizations.get(savedObjectId); const vis = new Vis(savedObject.visState.type, await convertToSerializedVis(savedObject)); - return createVisEmbeddableFromObject(vis, input, parent); + return createVisEmbeddableFromObject(this.deps)(vis, input, parent); } catch (e) { console.error(e); // eslint-disable-line no-console return new ErrorEmbeddable(e, input, parent); diff --git a/src/plugins/visualizations/public/mocks.ts b/src/plugins/visualizations/public/mocks.ts index 2aa346423297a3..d6eeffdb014598 100644 --- a/src/plugins/visualizations/public/mocks.ts +++ b/src/plugins/visualizations/public/mocks.ts @@ -26,6 +26,7 @@ import { expressionsPluginMock } from '../../../plugins/expressions/public/mocks import { dataPluginMock } from '../../../plugins/data/public/mocks'; import { usageCollectionPluginMock } from '../../../plugins/usage_collection/public/mocks'; import { uiActionsPluginMock } from '../../../plugins/ui_actions/public/mocks'; +import { inspectorPluginMock } from '../../../plugins/inspector/public/mocks'; const createSetupContract = (): VisualizationsSetup => ({ createBaseVisualization: jest.fn(), @@ -53,14 +54,16 @@ const createInstance = async () => { const setup = plugin.setup(coreMock.createSetup(), { data: dataPluginMock.createSetupContract(), - expressions: expressionsPluginMock.createSetupContract(), embeddable: embeddablePluginMock.createSetupContract(), + expressions: expressionsPluginMock.createSetupContract(), + inspector: inspectorPluginMock.createSetupContract(), usageCollection: usageCollectionPluginMock.createSetupContract(), }); const doStart = () => plugin.start(coreMock.createStart(), { data: dataPluginMock.createStartContract(), expressions: expressionsPluginMock.createStartContract(), + inspector: inspectorPluginMock.createStartContract(), uiActions: uiActionsPluginMock.createStartContract(), }); diff --git a/src/plugins/visualizations/public/plugin.ts b/src/plugins/visualizations/public/plugin.ts index 8fcb84b19a9be8..b3e8c9b5b61b3a 100644 --- a/src/plugins/visualizations/public/plugin.ts +++ b/src/plugins/visualizations/public/plugin.ts @@ -43,18 +43,23 @@ import { VisualizeEmbeddableFactory, createVisEmbeddableFromObject, } from './embeddable'; -import { ExpressionsSetup, ExpressionsStart } from '../../../plugins/expressions/public'; -import { EmbeddableSetup } from '../../../plugins/embeddable/public'; +import { ExpressionsSetup, ExpressionsStart } from '../../expressions/public'; +import { EmbeddableSetup } from '../../embeddable/public'; import { visualization as visualizationFunction } from './expressions/visualization_function'; import { visualization as visualizationRenderer } from './expressions/visualization_renderer'; import { range as rangeExpressionFunction } from './expression_functions/range'; import { visDimension as visDimensionExpressionFunction } from './expression_functions/vis_dimension'; import { DataPublicPluginSetup, DataPublicPluginStart } from '../../../plugins/data/public'; -import { UsageCollectionSetup } from '../../../plugins/usage_collection/public'; +import { + Setup as InspectorSetup, + Start as InspectorStart, +} from '../../../plugins/inspector/public'; +import { UsageCollectionSetup } from '../../usage_collection/public'; +import { createStartServicesGetter, StartServicesGetter } from '../../kibana_utils/public'; import { createSavedVisLoader, SavedVisualizationsLoader } from './saved_visualizations'; import { SerializedVis, Vis } from './vis'; import { showNewVisModal } from './wizard'; -import { UiActionsStart } from '../../../plugins/ui_actions/public'; +import { UiActionsStart } from '../../ui_actions/public'; import { convertFromSerializedVis, convertToSerializedVis, @@ -74,19 +79,21 @@ export interface VisualizationsStart extends TypesStart { convertToSerializedVis: typeof convertToSerializedVis; convertFromSerializedVis: typeof convertFromSerializedVis; showNewVisModal: typeof showNewVisModal; - __LEGACY: { createVisEmbeddableFromObject: typeof createVisEmbeddableFromObject }; + __LEGACY: { createVisEmbeddableFromObject: ReturnType }; } export interface VisualizationsSetupDeps { - expressions: ExpressionsSetup; + data: DataPublicPluginSetup; embeddable: EmbeddableSetup; + expressions: ExpressionsSetup; + inspector: InspectorSetup; usageCollection: UsageCollectionSetup; - data: DataPublicPluginSetup; } export interface VisualizationsStartDeps { data: DataPublicPluginStart; expressions: ExpressionsStart; + inspector: InspectorStart; uiActions: UiActionsStart; } @@ -107,13 +114,16 @@ export class VisualizationsPlugin VisualizationsStartDeps > { private readonly types: TypesService = new TypesService(); + private getStartServicesOrDie?: StartServicesGetter; constructor(initializerContext: PluginInitializerContext) {} public setup( - core: CoreSetup, + core: CoreSetup, { expressions, embeddable, usageCollection, data }: VisualizationsSetupDeps ): VisualizationsSetup { + const start = (this.getStartServicesOrDie = createStartServicesGetter(core.getStartServices)); + setUISettings(core.uiSettings); setUsageCollector(usageCollection); @@ -122,7 +132,7 @@ export class VisualizationsPlugin expressions.registerFunction(rangeExpressionFunction); expressions.registerFunction(visDimensionExpressionFunction); - const embeddableFactory = new VisualizeEmbeddableFactory(); + const embeddableFactory = new VisualizeEmbeddableFactory({ start }); embeddable.registerEmbeddableFactory(VISUALIZE_EMBEDDABLE_TYPE, embeddableFactory); return { @@ -171,7 +181,11 @@ export class VisualizationsPlugin convertToSerializedVis, convertFromSerializedVis, savedVisualizationsLoader, - __LEGACY: { createVisEmbeddableFromObject }, + __LEGACY: { + createVisEmbeddableFromObject: createVisEmbeddableFromObject({ + start: this.getStartServicesOrDie!, + }), + }, }; } diff --git a/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts b/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts index 26f8278cd3d434..83d53d27e41fdc 100644 --- a/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts +++ b/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts @@ -1460,4 +1460,62 @@ describe('migration visualization', () => { expect(migratedParams.gauge_color_rules[1]).toEqual(params.gauge_color_rules[1]); }); }); + + describe('7.8.0 tsvb split_color_mode', () => { + const migrate = (doc: any) => + visualizationSavedObjectTypeMigrations['7.8.0']( + doc as Parameters[0], + savedObjectMigrationContext + ); + + const generateDoc = (params: any) => ({ + attributes: { + title: 'My Vis', + type: 'visualization', + description: 'This is my super cool vis.', + visState: JSON.stringify(params), + uiStateJSON: '{}', + version: 1, + kibanaSavedObjectMeta: { + searchSourceJSON: '{}', + }, + }, + }); + + it('should change a missing split_color_mode to gradient', () => { + const params = { type: 'metrics', params: { series: [{}] } }; + const testDoc1 = generateDoc(params); + const migratedTestDoc1 = migrate(testDoc1); + const series = JSON.parse(migratedTestDoc1.attributes.visState).params.series; + + expect(series[0].split_color_mode).toEqual('gradient'); + }); + + it('should not change the color mode if it is set', () => { + const params = { type: 'metrics', params: { series: [{ split_color_mode: 'gradient' }] } }; + const testDoc1 = generateDoc(params); + const migratedTestDoc1 = migrate(testDoc1); + const series = JSON.parse(migratedTestDoc1.attributes.visState).params.series; + + expect(series[0].split_color_mode).toEqual('gradient'); + }); + + it('should not change the color mode if it is non-default', () => { + const params = { type: 'metrics', params: { series: [{ split_color_mode: 'rainbow' }] } }; + const testDoc1 = generateDoc(params); + const migratedTestDoc1 = migrate(testDoc1); + const series = JSON.parse(migratedTestDoc1.attributes.visState).params.series; + + expect(series[0].split_color_mode).toEqual('rainbow'); + }); + + it('should not migrate a visualization of unknown type', () => { + const params = { type: 'unknown', params: { series: [{}] } }; + const doc = generateDoc(params); + const migratedDoc = migrate(doc); + const series = JSON.parse(migratedDoc.attributes.visState).params.series; + + expect(series[0].split_color_mode).toBeUndefined(); + }); + }); }); diff --git a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts index 80783e41863eaf..94473e35a942d5 100644 --- a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts +++ b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts @@ -602,7 +602,39 @@ const migrateMatchAllQuery: SavedObjectMigrationFn = doc => { }; } } + return doc; +}; + +// [TSVB] Default color palette is changing, keep the default for older viz +const migrateTsvbDefaultColorPalettes: SavedObjectMigrationFn = doc => { + const visStateJSON = get(doc, 'attributes.visState'); + let visState; + + if (visStateJSON) { + try { + visState = JSON.parse(visStateJSON); + } catch (e) { + // Let it go, the data is invalid and we'll leave it as is + } + if (visState && visState.type === 'metrics') { + const series: any[] = get(visState, 'params.series') || []; + series.forEach(part => { + // The default value was not saved before + if (!part.split_color_mode) { + part.split_color_mode = 'gradient'; + } + }); + + return { + ...doc, + attributes: { + ...doc.attributes, + visState: JSON.stringify(visState), + }, + }; + } + } return doc; }; @@ -639,4 +671,5 @@ export const visualizationSavedObjectTypeMigrations = { '7.3.1': flow(migrateFiltersAggQueryStringQueries), '7.4.2': flow(transformSplitFiltersStringToQueryObject), '7.7.0': flow(migrateOperatorKeyTypo), + '7.8.0': flow(migrateTsvbDefaultColorPalettes), }; diff --git a/test/functional/apps/visualize/_tsvb_time_series.ts b/test/functional/apps/visualize/_tsvb_time_series.ts index fa79190a5bf940..ac89c2b55e5140 100644 --- a/test/functional/apps/visualize/_tsvb_time_series.ts +++ b/test/functional/apps/visualize/_tsvb_time_series.ts @@ -25,7 +25,6 @@ export default function({ getPageObjects, getService }: FtrProviderContext) { const retry = getService('retry'); const log = getService('log'); const kibanaServer = getService('kibanaServer'); - const testSubjects = getService('testSubjects'); describe('visual builder', function describeIndexTests() { beforeEach(async () => { @@ -126,20 +125,18 @@ export default function({ getPageObjects, getService }: FtrProviderContext) { expect(actualCountMin).to.be('3 hours'); }); - // --reversed class is not implemented in @elastic\chart - describe.skip('Dark mode', () => { + describe('Dark mode', () => { before(async () => { await kibanaServer.uiSettings.update({ 'theme:darkMode': true, }); }); - it(`viz should have 'reversed' class when background color is white`, async () => { + it(`viz should have light class when background color is white`, async () => { await visualBuilder.clickPanelOptions('timeSeries'); await visualBuilder.setBackgroundColor('#FFFFFF'); - const classNames = await testSubjects.getAttribute('timeseriesChart', 'class'); - expect(classNames.includes('tvbVisTimeSeries--reversed')).to.be(true); + expect(await visualBuilder.checkTimeSeriesIsLight()).to.be(true); }); after(async () => { diff --git a/test/functional/page_objects/visual_builder_page.ts b/test/functional/page_objects/visual_builder_page.ts index b8e6c812b46bd5..12962b3a5cdef7 100644 --- a/test/functional/page_objects/visual_builder_page.ts +++ b/test/functional/page_objects/visual_builder_page.ts @@ -71,6 +71,10 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }: FtrPro } } + public async checkTimeSeriesIsLight() { + return await find.existsByCssSelector('.tvbVisTimeSeriesLight'); + } + public async checkTimeSeriesLegendIsPresent() { const isPresent = await find.existsByCssSelector('.echLegend'); if (!isPresent) { diff --git a/x-pack/legacy/plugins/maps/common/get_join_key.ts b/x-pack/legacy/plugins/maps/common/get_join_key.ts deleted file mode 100644 index 004f12ca08d2ea..00000000000000 --- a/x-pack/legacy/plugins/maps/common/get_join_key.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -export * from '../../../../plugins/maps/common/get_join_key'; diff --git a/x-pack/legacy/plugins/maps/common/i18n_getters.ts b/x-pack/legacy/plugins/maps/common/i18n_getters.ts deleted file mode 100644 index f9d186dea2e2b9..00000000000000 --- a/x-pack/legacy/plugins/maps/common/i18n_getters.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -export * from '../../../../plugins/maps/common/i18n_getters'; diff --git a/x-pack/legacy/plugins/maps/common/parse_xml_string.js b/x-pack/legacy/plugins/maps/common/parse_xml_string.js deleted file mode 100644 index 34ec1444728281..00000000000000 --- a/x-pack/legacy/plugins/maps/common/parse_xml_string.js +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -export * from '../../../../plugins/maps/common/parse_xml_string'; diff --git a/x-pack/legacy/plugins/maps/index.js b/x-pack/legacy/plugins/maps/index.js index f4e01efc05f45f..8546e3712c7630 100644 --- a/x-pack/legacy/plugins/maps/index.js +++ b/x-pack/legacy/plugins/maps/index.js @@ -9,9 +9,14 @@ import mappings from './mappings.json'; import { i18n } from '@kbn/i18n'; import { resolve } from 'path'; import { migrations } from './migrations'; -import { getAppTitle } from './common/i18n_getters'; +import { getAppTitle } from '../../../plugins/maps/common/i18n_getters'; import { MapPlugin } from './server/plugin'; -import { APP_ID, APP_ICON, createMapPath, MAP_SAVED_OBJECT_TYPE } from './common/constants'; +import { + APP_ID, + APP_ICON, + createMapPath, + MAP_SAVED_OBJECT_TYPE, +} from '../../../plugins/maps/common/constants'; import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/utils'; export function maps(kibana) { @@ -53,7 +58,6 @@ export function maps(kibana) { }; }, embeddableFactories: ['plugins/maps/embeddable/map_embeddable_factory'], - home: ['plugins/maps/legacy_register_feature'], styleSheetPaths: `${__dirname}/public/index.scss`, savedObjectSchemas: { 'maps-telemetry': { @@ -78,7 +82,6 @@ export function maps(kibana) { }, mappings, migrations, - hacks: ['plugins/maps/register_vis_type_alias'], }, config(Joi) { return Joi.object({ diff --git a/x-pack/legacy/plugins/maps/migrations.js b/x-pack/legacy/plugins/maps/migrations.js index a8e69eef7a02fd..d3666025082b78 100644 --- a/x-pack/legacy/plugins/maps/migrations.js +++ b/x-pack/legacy/plugins/maps/migrations.js @@ -4,14 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { extractReferences } from './common/migrations/references'; -import { emsRasterTileToEmsVectorTile } from './common/migrations/ems_raster_tile_to_ems_vector_tile'; -import { topHitsTimeToSort } from './common/migrations/top_hits_time_to_sort'; -import { moveApplyGlobalQueryToSources } from './common/migrations/move_apply_global_query'; -import { addFieldMetaOptions } from './common/migrations/add_field_meta_options'; -import { migrateSymbolStyleDescriptor } from './common/migrations/migrate_symbol_style_descriptor'; -import { migrateUseTopHitsToScalingType } from './common/migrations/scaling_type'; -import { migrateJoinAggKey } from './common/migrations/join_agg_key'; +import { extractReferences } from '../../../plugins/maps/common/migrations/references'; +import { emsRasterTileToEmsVectorTile } from '../../../plugins/maps/common/migrations/ems_raster_tile_to_ems_vector_tile'; +import { topHitsTimeToSort } from '../../../plugins/maps/common/migrations/top_hits_time_to_sort'; +import { moveApplyGlobalQueryToSources } from '../../../plugins/maps/common/migrations/move_apply_global_query'; +import { addFieldMetaOptions } from '../../../plugins/maps/common/migrations/add_field_meta_options'; +import { migrateSymbolStyleDescriptor } from '../../../plugins/maps/common/migrations/migrate_symbol_style_descriptor'; +import { migrateUseTopHitsToScalingType } from '../../../plugins/maps/common/migrations/scaling_type'; +import { migrateJoinAggKey } from '../../../plugins/maps/common/migrations/join_agg_key'; export const migrations = { map: { diff --git a/x-pack/legacy/plugins/maps/public/actions/map_actions.d.ts b/x-pack/legacy/plugins/maps/public/actions/map_actions.d.ts deleted file mode 100644 index 34f8c30b51874b..00000000000000 --- a/x-pack/legacy/plugins/maps/public/actions/map_actions.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -/* eslint-disable @typescript-eslint/consistent-type-definitions */ - -export * from '../../../../../plugins/maps/public/actions/map_actions'; diff --git a/x-pack/legacy/plugins/maps/public/actions/map_actions.js b/x-pack/legacy/plugins/maps/public/actions/map_actions.js deleted file mode 100644 index 7bfbf5761c5b8c..00000000000000 --- a/x-pack/legacy/plugins/maps/public/actions/map_actions.js +++ /dev/null @@ -1,978 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import _ from 'lodash'; -import turf from 'turf'; -import turfBooleanContains from '@turf/boolean-contains'; -import uuid from 'uuid/v4'; -import { - getLayerList, - getLayerListRaw, - getDataFilters, - getSelectedLayerId, - getMapReady, - getWaitingForMapReadyLayerListRaw, - getTransientLayerId, - getOpenTooltips, - getQuery, - getDataRequestDescriptor, -} from '../selectors/map_selectors'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { FLYOUT_STATE } from '../../../../../plugins/maps/public/reducers/ui'; -import { - cancelRequest, - registerCancelCallback, - unregisterCancelCallback, - getEventHandlers, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../plugins/maps/public/reducers/non_serializable_instances'; -import { updateFlyout } from '../actions/ui_actions'; -import { - FEATURE_ID_PROPERTY_NAME, - LAYER_TYPE, - SOURCE_DATA_ID_ORIGIN, -} from '../../common/constants'; - -import { - SET_SELECTED_LAYER, - SET_TRANSIENT_LAYER, - UPDATE_LAYER_ORDER, - ADD_LAYER, - SET_LAYER_ERROR_STATUS, - ADD_WAITING_FOR_MAP_READY_LAYER, - CLEAR_WAITING_FOR_MAP_READY_LAYER_LIST, - REMOVE_LAYER, - SET_LAYER_VISIBILITY, - MAP_EXTENT_CHANGED, - MAP_READY, - MAP_DESTROYED, - LAYER_DATA_LOAD_STARTED, - LAYER_DATA_LOAD_ENDED, - LAYER_DATA_LOAD_ERROR, - UPDATE_SOURCE_DATA_REQUEST, - SET_JOINS, - SET_QUERY, - TRIGGER_REFRESH_TIMER, - UPDATE_LAYER_PROP, - UPDATE_LAYER_STYLE, - SET_LAYER_STYLE_META, - UPDATE_SOURCE_PROP, - SET_REFRESH_CONFIG, - SET_MOUSE_COORDINATES, - CLEAR_MOUSE_COORDINATES, - SET_GOTO, - CLEAR_GOTO, - TRACK_CURRENT_LAYER_STATE, - ROLLBACK_TO_TRACKED_LAYER_STATE, - REMOVE_TRACKED_LAYER_STATE, - SET_OPEN_TOOLTIPS, - UPDATE_DRAW_STATE, - SET_SCROLL_ZOOM, - SET_MAP_INIT_ERROR, - SET_INTERACTIVE, - DISABLE_TOOLTIP_CONTROL, - HIDE_TOOLBAR_OVERLAY, - HIDE_LAYER_CONTROL, - HIDE_VIEW_CONTROL, - SET_WAITING_FOR_READY_HIDDEN_LAYERS, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../plugins/maps/public/actions/map_actions'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -export * from '../../../../../plugins/maps/public/actions/map_actions'; - -function getLayerLoadingCallbacks(dispatch, getState, layerId) { - return { - startLoading: (dataId, requestToken, meta) => - dispatch(startDataLoad(layerId, dataId, requestToken, meta)), - stopLoading: (dataId, requestToken, data, meta) => - dispatch(endDataLoad(layerId, dataId, requestToken, data, meta)), - onLoadError: (dataId, requestToken, errorMessage) => - dispatch(onDataLoadError(layerId, dataId, requestToken, errorMessage)), - updateSourceData: newData => { - dispatch(updateSourceDataRequest(layerId, newData)); - }, - isRequestStillActive: (dataId, requestToken) => { - const dataRequest = getDataRequestDescriptor(getState(), layerId, dataId); - if (!dataRequest) { - return false; - } - return dataRequest.dataRequestToken === requestToken; - }, - registerCancelCallback: (requestToken, callback) => - dispatch(registerCancelCallback(requestToken, callback)), - }; -} - -function getLayerById(layerId, state) { - return getLayerList(state).find(layer => { - return layerId === layer.getId(); - }); -} - -async function syncDataForAllLayers(dispatch, getState, dataFilters) { - const state = getState(); - const layerList = getLayerList(state); - const syncs = layerList.map(layer => { - const loadingFunctions = getLayerLoadingCallbacks(dispatch, getState, layer.getId()); - return layer.syncData({ ...loadingFunctions, dataFilters }); - }); - await Promise.all(syncs); -} - -export function cancelAllInFlightRequests() { - return (dispatch, getState) => { - getLayerList(getState()).forEach(layer => { - dispatch(clearDataRequests(layer)); - }); - }; -} - -function clearDataRequests(layer) { - return dispatch => { - layer.getInFlightRequestTokens().forEach(requestToken => { - dispatch(cancelRequest(requestToken)); - }); - dispatch({ - type: UPDATE_LAYER_PROP, - id: layer.getId(), - propName: '__dataRequests', - newValue: [], - }); - }; -} - -export function setMapInitError(errorMessage) { - return { - type: SET_MAP_INIT_ERROR, - errorMessage, - }; -} - -export function trackCurrentLayerState(layerId) { - return { - type: TRACK_CURRENT_LAYER_STATE, - layerId: layerId, - }; -} - -export function rollbackToTrackedLayerStateForSelectedLayer() { - return async (dispatch, getState) => { - const layerId = getSelectedLayerId(getState()); - await dispatch({ - type: ROLLBACK_TO_TRACKED_LAYER_STATE, - layerId: layerId, - }); - - // Ensure updateStyleMeta is triggered - // syncDataForLayer may not trigger endDataLoad if no re-fetch is required - dispatch(updateStyleMeta(layerId)); - - dispatch(syncDataForLayer(layerId)); - }; -} - -export function removeTrackedLayerStateForSelectedLayer() { - return (dispatch, getState) => { - const layerId = getSelectedLayerId(getState()); - dispatch({ - type: REMOVE_TRACKED_LAYER_STATE, - layerId: layerId, - }); - }; -} - -export function replaceLayerList(newLayerList) { - return (dispatch, getState) => { - const isMapReady = getMapReady(getState()); - if (!isMapReady) { - dispatch({ - type: CLEAR_WAITING_FOR_MAP_READY_LAYER_LIST, - }); - } else { - getLayerListRaw(getState()).forEach(({ id }) => { - dispatch(removeLayerFromLayerList(id)); - }); - } - - newLayerList.forEach(layerDescriptor => { - dispatch(addLayer(layerDescriptor)); - }); - }; -} - -export function cloneLayer(layerId) { - return async (dispatch, getState) => { - const layer = getLayerById(layerId, getState()); - if (!layer) { - return; - } - - const clonedDescriptor = await layer.cloneDescriptor(); - dispatch(addLayer(clonedDescriptor)); - }; -} - -export function addLayer(layerDescriptor) { - return (dispatch, getState) => { - const isMapReady = getMapReady(getState()); - if (!isMapReady) { - dispatch({ - type: ADD_WAITING_FOR_MAP_READY_LAYER, - layer: layerDescriptor, - }); - return; - } - - dispatch({ - type: ADD_LAYER, - layer: layerDescriptor, - }); - dispatch(syncDataForLayer(layerDescriptor.id)); - }; -} - -// Do not use when rendering a map. Method exists to enable selectors for getLayerList when -// rendering is not needed. -export function addLayerWithoutDataSync(layerDescriptor) { - return { - type: ADD_LAYER, - layer: layerDescriptor, - }; -} - -function setLayerDataLoadErrorStatus(layerId, errorMessage) { - return dispatch => { - dispatch({ - type: SET_LAYER_ERROR_STATUS, - isInErrorState: errorMessage !== null, - layerId, - errorMessage, - }); - }; -} - -export function cleanTooltipStateForLayer(layerId, layerFeatures = []) { - return (dispatch, getState) => { - let featuresRemoved = false; - const openTooltips = getOpenTooltips(getState()) - .map(tooltipState => { - const nextFeatures = tooltipState.features.filter(tooltipFeature => { - if (tooltipFeature.layerId !== layerId) { - // feature from another layer, keep it - return true; - } - - // Keep feature if it is still in layer - return layerFeatures.some(layerFeature => { - return layerFeature.properties[FEATURE_ID_PROPERTY_NAME] === tooltipFeature.id; - }); - }); - - if (tooltipState.features.length !== nextFeatures.length) { - featuresRemoved = true; - } - - return { ...tooltipState, features: nextFeatures }; - }) - .filter(tooltipState => { - return tooltipState.features.length > 0; - }); - - if (featuresRemoved) { - dispatch({ - type: SET_OPEN_TOOLTIPS, - openTooltips, - }); - } - }; -} - -export function setLayerVisibility(layerId, makeVisible) { - return async (dispatch, getState) => { - //if the current-state is invisible, we also want to sync data - //e.g. if a layer was invisible at start-up, it won't have any data loaded - const layer = getLayerById(layerId, getState()); - - // If the layer visibility is already what we want it to be, do nothing - if (!layer || layer.isVisible() === makeVisible) { - return; - } - - if (!makeVisible) { - dispatch(cleanTooltipStateForLayer(layerId)); - } - - await dispatch({ - type: SET_LAYER_VISIBILITY, - layerId, - visibility: makeVisible, - }); - if (makeVisible) { - dispatch(syncDataForLayer(layerId)); - } - }; -} - -export function toggleLayerVisible(layerId) { - return async (dispatch, getState) => { - const layer = getLayerById(layerId, getState()); - if (!layer) { - return; - } - const makeVisible = !layer.isVisible(); - - dispatch(setLayerVisibility(layerId, makeVisible)); - }; -} - -export function setSelectedLayer(layerId) { - return async (dispatch, getState) => { - const oldSelectedLayer = getSelectedLayerId(getState()); - if (oldSelectedLayer) { - await dispatch(rollbackToTrackedLayerStateForSelectedLayer()); - } - if (layerId) { - dispatch(trackCurrentLayerState(layerId)); - } - dispatch({ - type: SET_SELECTED_LAYER, - selectedLayerId: layerId, - }); - }; -} - -export function removeTransientLayer() { - return async (dispatch, getState) => { - const transientLayerId = getTransientLayerId(getState()); - if (transientLayerId) { - await dispatch(removeLayerFromLayerList(transientLayerId)); - await dispatch(setTransientLayer(null)); - } - }; -} - -export function setTransientLayer(layerId) { - return { - type: SET_TRANSIENT_LAYER, - transientLayerId: layerId, - }; -} - -export function clearTransientLayerStateAndCloseFlyout() { - return async dispatch => { - await dispatch(updateFlyout(FLYOUT_STATE.NONE)); - await dispatch(setSelectedLayer(null)); - await dispatch(removeTransientLayer()); - }; -} - -export function updateLayerOrder(newLayerOrder) { - return { - type: UPDATE_LAYER_ORDER, - newLayerOrder, - }; -} - -export function mapReady() { - return (dispatch, getState) => { - dispatch({ - type: MAP_READY, - }); - - getWaitingForMapReadyLayerListRaw(getState()).forEach(layerDescriptor => { - dispatch(addLayer(layerDescriptor)); - }); - - dispatch({ - type: CLEAR_WAITING_FOR_MAP_READY_LAYER_LIST, - }); - }; -} - -export function mapDestroyed() { - return { - type: MAP_DESTROYED, - }; -} - -export function mapExtentChanged(newMapConstants) { - return async (dispatch, getState) => { - const state = getState(); - const dataFilters = getDataFilters(state); - const { extent, zoom: newZoom } = newMapConstants; - const { buffer, zoom: currentZoom } = dataFilters; - - if (extent) { - let doesBufferContainExtent = false; - if (buffer) { - const bufferGeometry = turf.bboxPolygon([ - buffer.minLon, - buffer.minLat, - buffer.maxLon, - buffer.maxLat, - ]); - const extentGeometry = turf.bboxPolygon([ - extent.minLon, - extent.minLat, - extent.maxLon, - extent.maxLat, - ]); - - doesBufferContainExtent = turfBooleanContains(bufferGeometry, extentGeometry); - } - - if (!doesBufferContainExtent || currentZoom !== newZoom) { - const scaleFactor = 0.5; // TODO put scale factor in store and fetch with selector - const width = extent.maxLon - extent.minLon; - const height = extent.maxLat - extent.minLat; - dataFilters.buffer = { - minLon: extent.minLon - width * scaleFactor, - minLat: extent.minLat - height * scaleFactor, - maxLon: extent.maxLon + width * scaleFactor, - maxLat: extent.maxLat + height * scaleFactor, - }; - } - } - - dispatch({ - type: MAP_EXTENT_CHANGED, - mapState: { - ...dataFilters, - ...newMapConstants, - }, - }); - const newDataFilters = { ...dataFilters, ...newMapConstants }; - await syncDataForAllLayers(dispatch, getState, newDataFilters); - }; -} - -export function closeOnClickTooltip(tooltipId) { - return (dispatch, getState) => { - dispatch({ - type: SET_OPEN_TOOLTIPS, - openTooltips: getOpenTooltips(getState()).filter(({ id }) => { - return tooltipId !== id; - }), - }); - }; -} - -export function openOnClickTooltip(tooltipState) { - return (dispatch, getState) => { - const openTooltips = getOpenTooltips(getState()).filter(({ features, location, isLocked }) => { - return ( - isLocked && - !_.isEqual(location, tooltipState.location) && - !_.isEqual(features, tooltipState.features) - ); - }); - - openTooltips.push({ - ...tooltipState, - isLocked: true, - id: uuid(), - }); - - dispatch({ - type: SET_OPEN_TOOLTIPS, - openTooltips, - }); - }; -} - -export function closeOnHoverTooltip() { - return (dispatch, getState) => { - if (getOpenTooltips(getState()).length) { - dispatch({ - type: SET_OPEN_TOOLTIPS, - openTooltips: [], - }); - } - }; -} - -export function openOnHoverTooltip(tooltipState) { - return { - type: SET_OPEN_TOOLTIPS, - openTooltips: [ - { - ...tooltipState, - isLocked: false, - id: uuid(), - }, - ], - }; -} - -export function setMouseCoordinates({ lat, lon }) { - let safeLon = lon; - if (lon > 180) { - const overlapWestOfDateLine = lon - 180; - safeLon = -180 + overlapWestOfDateLine; - } else if (lon < -180) { - const overlapEastOfDateLine = Math.abs(lon) - 180; - safeLon = 180 - overlapEastOfDateLine; - } - - return { - type: SET_MOUSE_COORDINATES, - lat, - lon: safeLon, - }; -} - -export function clearMouseCoordinates() { - return { type: CLEAR_MOUSE_COORDINATES }; -} - -export function disableScrollZoom() { - return { type: SET_SCROLL_ZOOM, scrollZoom: false }; -} - -export function fitToLayerExtent(layerId) { - return async function(dispatch, getState) { - const targetLayer = getLayerById(layerId, getState()); - - if (targetLayer) { - const dataFilters = getDataFilters(getState()); - const bounds = await targetLayer.getBounds(dataFilters); - if (bounds) { - await dispatch(setGotoWithBounds(bounds)); - } - } - }; -} - -export function setGotoWithBounds(bounds) { - return { - type: SET_GOTO, - bounds: bounds, - }; -} - -export function setGotoWithCenter({ lat, lon, zoom }) { - return { - type: SET_GOTO, - center: { lat, lon, zoom }, - }; -} - -export function clearGoto() { - return { type: CLEAR_GOTO }; -} - -export function startDataLoad(layerId, dataId, requestToken, meta = {}) { - return (dispatch, getState) => { - const layer = getLayerById(layerId, getState()); - if (layer) { - dispatch(cancelRequest(layer.getPrevRequestToken(dataId))); - } - - const eventHandlers = getEventHandlers(getState()); - if (eventHandlers && eventHandlers.onDataLoad) { - eventHandlers.onDataLoad({ - layerId, - dataId, - }); - } - - dispatch({ - meta, - type: LAYER_DATA_LOAD_STARTED, - layerId, - dataId, - requestToken, - }); - }; -} - -export function updateSourceDataRequest(layerId, newData) { - return dispatch => { - dispatch({ - type: UPDATE_SOURCE_DATA_REQUEST, - dataId: SOURCE_DATA_ID_ORIGIN, - layerId, - newData, - }); - - dispatch(updateStyleMeta(layerId)); - }; -} - -export function endDataLoad(layerId, dataId, requestToken, data, meta) { - return async (dispatch, getState) => { - dispatch(unregisterCancelCallback(requestToken)); - - const features = data && data.features ? data.features : []; - - const eventHandlers = getEventHandlers(getState()); - if (eventHandlers && eventHandlers.onDataLoadEnd) { - const layer = getLayerById(layerId, getState()); - const resultMeta = {}; - if (layer && layer.getType() === LAYER_TYPE.VECTOR) { - resultMeta.featuresCount = features.length; - } - - eventHandlers.onDataLoadEnd({ - layerId, - dataId, - resultMeta, - }); - } - - dispatch(cleanTooltipStateForLayer(layerId, features)); - dispatch({ - type: LAYER_DATA_LOAD_ENDED, - layerId, - dataId, - data, - meta, - requestToken, - }); - - //Clear any data-load errors when there is a succesful data return. - //Co this on end-data-load iso at start-data-load to avoid blipping the error status between true/false. - //This avoids jitter in the warning icon of the TOC when the requests continues to return errors. - dispatch(setLayerDataLoadErrorStatus(layerId, null)); - - dispatch(updateStyleMeta(layerId)); - }; -} - -export function onDataLoadError(layerId, dataId, requestToken, errorMessage) { - return async (dispatch, getState) => { - dispatch(unregisterCancelCallback(requestToken)); - - const eventHandlers = getEventHandlers(getState()); - if (eventHandlers && eventHandlers.onDataLoadError) { - eventHandlers.onDataLoadError({ - layerId, - dataId, - errorMessage, - }); - } - - dispatch(cleanTooltipStateForLayer(layerId)); - dispatch({ - type: LAYER_DATA_LOAD_ERROR, - data: null, - layerId, - dataId, - requestToken, - }); - - dispatch(setLayerDataLoadErrorStatus(layerId, errorMessage)); - }; -} - -export function updateSourceProp(layerId, propName, value, newLayerType) { - return async dispatch => { - dispatch({ - type: UPDATE_SOURCE_PROP, - layerId, - propName, - value, - }); - if (newLayerType) { - dispatch(updateLayerType(layerId, newLayerType)); - } - await dispatch(clearMissingStyleProperties(layerId)); - dispatch(syncDataForLayer(layerId)); - }; -} - -function updateLayerType(layerId, newLayerType) { - return (dispatch, getState) => { - const layer = getLayerById(layerId, getState()); - if (!layer || layer.getType() === newLayerType) { - return; - } - dispatch(clearDataRequests(layer)); - dispatch({ - type: UPDATE_LAYER_PROP, - id: layerId, - propName: 'type', - newValue: newLayerType, - }); - }; -} - -export function syncDataForLayer(layerId) { - return async (dispatch, getState) => { - const targetLayer = getLayerById(layerId, getState()); - if (targetLayer) { - const dataFilters = getDataFilters(getState()); - const loadingFunctions = getLayerLoadingCallbacks(dispatch, getState, layerId); - await targetLayer.syncData({ - ...loadingFunctions, - dataFilters, - }); - } - }; -} - -export function updateLayerLabel(id, newLabel) { - return { - type: UPDATE_LAYER_PROP, - id, - propName: 'label', - newValue: newLabel, - }; -} - -export function updateLayerMinZoom(id, minZoom) { - return { - type: UPDATE_LAYER_PROP, - id, - propName: 'minZoom', - newValue: minZoom, - }; -} - -export function updateLayerMaxZoom(id, maxZoom) { - return { - type: UPDATE_LAYER_PROP, - id, - propName: 'maxZoom', - newValue: maxZoom, - }; -} - -export function updateLayerAlpha(id, alpha) { - return { - type: UPDATE_LAYER_PROP, - id, - propName: 'alpha', - newValue: alpha, - }; -} - -export function setLayerQuery(id, query) { - return dispatch => { - dispatch({ - type: UPDATE_LAYER_PROP, - id, - propName: 'query', - newValue: query, - }); - - dispatch(syncDataForLayer(id)); - }; -} - -export function removeSelectedLayer() { - return (dispatch, getState) => { - const state = getState(); - const layerId = getSelectedLayerId(state); - dispatch(removeLayer(layerId)); - }; -} - -export function removeLayer(layerId) { - return async (dispatch, getState) => { - const state = getState(); - const selectedLayerId = getSelectedLayerId(state); - if (layerId === selectedLayerId) { - dispatch(updateFlyout(FLYOUT_STATE.NONE)); - await dispatch(setSelectedLayer(null)); - } - dispatch(removeLayerFromLayerList(layerId)); - }; -} - -function removeLayerFromLayerList(layerId) { - return (dispatch, getState) => { - const layerGettingRemoved = getLayerById(layerId, getState()); - if (!layerGettingRemoved) { - return; - } - - layerGettingRemoved.getInFlightRequestTokens().forEach(requestToken => { - dispatch(cancelRequest(requestToken)); - }); - dispatch(cleanTooltipStateForLayer(layerId)); - layerGettingRemoved.destroy(); - dispatch({ - type: REMOVE_LAYER, - id: layerId, - }); - }; -} - -export function setQuery({ query, timeFilters, filters = [], refresh = false }) { - function generateQueryTimestamp() { - return new Date().toISOString(); - } - return async (dispatch, getState) => { - const prevQuery = getQuery(getState()); - const prevTriggeredAt = - prevQuery && prevQuery.queryLastTriggeredAt - ? prevQuery.queryLastTriggeredAt - : generateQueryTimestamp(); - - dispatch({ - type: SET_QUERY, - timeFilters, - query: { - ...query, - // ensure query changes to trigger re-fetch when "Refresh" clicked - queryLastTriggeredAt: refresh ? generateQueryTimestamp() : prevTriggeredAt, - }, - filters, - }); - - const dataFilters = getDataFilters(getState()); - await syncDataForAllLayers(dispatch, getState, dataFilters); - }; -} - -export function setRefreshConfig({ isPaused, interval }) { - return { - type: SET_REFRESH_CONFIG, - isPaused, - interval, - }; -} - -export function triggerRefreshTimer() { - return async (dispatch, getState) => { - dispatch({ - type: TRIGGER_REFRESH_TIMER, - }); - - const dataFilters = getDataFilters(getState()); - await syncDataForAllLayers(dispatch, getState, dataFilters); - }; -} - -export function clearMissingStyleProperties(layerId) { - return async (dispatch, getState) => { - const targetLayer = getLayerById(layerId, getState()); - if (!targetLayer) { - return; - } - - const style = targetLayer.getCurrentStyle(); - if (!style) { - return; - } - - const nextFields = await targetLayer.getFields(); //take into account all fields, since labels can be driven by any field (source or join) - const { hasChanges, nextStyleDescriptor } = style.getDescriptorWithMissingStylePropsRemoved( - nextFields - ); - if (hasChanges) { - dispatch(updateLayerStyle(layerId, nextStyleDescriptor)); - } - }; -} - -export function updateLayerStyle(layerId, styleDescriptor) { - return dispatch => { - dispatch({ - type: UPDATE_LAYER_STYLE, - layerId, - style: { - ...styleDescriptor, - }, - }); - - // Ensure updateStyleMeta is triggered - // syncDataForLayer may not trigger endDataLoad if no re-fetch is required - dispatch(updateStyleMeta(layerId)); - - // Style update may require re-fetch, for example ES search may need to retrieve field used for dynamic styling - dispatch(syncDataForLayer(layerId)); - }; -} - -export function updateStyleMeta(layerId) { - return async (dispatch, getState) => { - const layer = getLayerById(layerId, getState()); - if (!layer) { - return; - } - const sourceDataRequest = layer.getSourceDataRequest(); - const style = layer.getCurrentStyle(); - if (!style || !sourceDataRequest) { - return; - } - const styleMeta = await style.pluckStyleMetaFromSourceDataRequest(sourceDataRequest); - dispatch({ - type: SET_LAYER_STYLE_META, - layerId, - styleMeta, - }); - }; -} - -export function updateLayerStyleForSelectedLayer(styleDescriptor) { - return (dispatch, getState) => { - const selectedLayerId = getSelectedLayerId(getState()); - if (!selectedLayerId) { - return; - } - dispatch(updateLayerStyle(selectedLayerId, styleDescriptor)); - }; -} - -export function setJoinsForLayer(layer, joins) { - return async dispatch => { - await dispatch({ - type: SET_JOINS, - layer: layer, - joins: joins, - }); - - await dispatch(clearMissingStyleProperties(layer.getId())); - dispatch(syncDataForLayer(layer.getId())); - }; -} - -export function updateDrawState(drawState) { - return dispatch => { - if (drawState !== null) { - dispatch({ type: SET_OPEN_TOOLTIPS, openTooltips: [] }); // tooltips just get in the way - } - dispatch({ - type: UPDATE_DRAW_STATE, - drawState: drawState, - }); - }; -} - -export function disableInteractive() { - return { type: SET_INTERACTIVE, disableInteractive: true }; -} - -export function disableTooltipControl() { - return { type: DISABLE_TOOLTIP_CONTROL, disableTooltipControl: true }; -} - -export function hideToolbarOverlay() { - return { type: HIDE_TOOLBAR_OVERLAY, hideToolbarOverlay: true }; -} - -export function hideLayerControl() { - return { type: HIDE_LAYER_CONTROL, hideLayerControl: true }; -} -export function hideViewControl() { - return { type: HIDE_VIEW_CONTROL, hideViewControl: true }; -} - -export function setHiddenLayers(hiddenLayerIds) { - return (dispatch, getState) => { - const isMapReady = getMapReady(getState()); - - if (!isMapReady) { - dispatch({ type: SET_WAITING_FOR_READY_HIDDEN_LAYERS, hiddenLayerIds }); - } else { - getLayerListRaw(getState()).forEach(layer => - dispatch(setLayerVisibility(layer.id, !hiddenLayerIds.includes(layer.id))) - ); - } - }; -} diff --git a/x-pack/legacy/plugins/maps/public/actions/ui_actions.js b/x-pack/legacy/plugins/maps/public/actions/ui_actions.js deleted file mode 100644 index 33ab2fd74122a6..00000000000000 --- a/x-pack/legacy/plugins/maps/public/actions/ui_actions.js +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { - UPDATE_FLYOUT, - CLOSE_SET_VIEW, - OPEN_SET_VIEW, - SET_IS_LAYER_TOC_OPEN, - SET_FULL_SCREEN, - SET_READ_ONLY, - SET_OPEN_TOC_DETAILS, - SHOW_TOC_DETAILS, - HIDE_TOC_DETAILS, - UPDATE_INDEXING_STAGE, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../plugins/maps/public/actions/ui_actions'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -export * from '../../../../../plugins/maps/public/actions/ui_actions'; - -export function exitFullScreen() { - return { - type: SET_FULL_SCREEN, - isFullScreen: false, - }; -} - -export function updateFlyout(display) { - return { - type: UPDATE_FLYOUT, - display, - }; -} -export function closeSetView() { - return { - type: CLOSE_SET_VIEW, - }; -} -export function openSetView() { - return { - type: OPEN_SET_VIEW, - }; -} -export function setIsLayerTOCOpen(isLayerTOCOpen) { - return { - type: SET_IS_LAYER_TOC_OPEN, - isLayerTOCOpen, - }; -} -export function enableFullScreen() { - return { - type: SET_FULL_SCREEN, - isFullScreen: true, - }; -} -export function setReadOnly(isReadOnly) { - return { - type: SET_READ_ONLY, - isReadOnly, - }; -} - -export function setOpenTOCDetails(layerIds) { - return { - type: SET_OPEN_TOC_DETAILS, - layerIds, - }; -} - -export function showTOCDetails(layerId) { - return { - type: SHOW_TOC_DETAILS, - layerId, - }; -} - -export function hideTOCDetails(layerId) { - return { - type: HIDE_TOC_DETAILS, - layerId, - }; -} - -export function updateIndexingStage(stage) { - return { - type: UPDATE_INDEXING_STAGE, - stage, - }; -} diff --git a/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.js b/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.js deleted file mode 100644 index 686259aeaaba44..00000000000000 --- a/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.js +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import _ from 'lodash'; -// Import each layer type, even those not used, to init in registry -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import '../../../../../plugins/maps/public/layers/sources/wms_source'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import '../../../../../plugins/maps/public/layers/sources/ems_file_source'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import '../../../../../plugins/maps/public/layers/sources/es_search_source'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import '../../../../../plugins/maps/public/layers/sources/es_pew_pew_source/es_pew_pew_source'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import '../../../../../plugins/maps/public/layers/sources/kibana_regionmap_source'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import '../../../../../plugins/maps/public/layers/sources/es_geo_grid_source'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import '../../../../../plugins/maps/public/layers/sources/xyz_tms_source'; - -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { KibanaTilemapSource } from '../../../../../plugins/maps/public/layers/sources/kibana_tilemap_source'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { EMSTMSSource } from '../../../../../plugins/maps/public/layers/sources/ems_tms_source'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getInjectedVarFunc } from '../../../../../plugins/maps/public/kibana_services'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getKibanaTileMap } from '../../../../../plugins/maps/public/meta'; - -export function getInitialLayers(layerListJSON, initialLayers = []) { - if (layerListJSON) { - return JSON.parse(layerListJSON); - } - - const tilemapSourceFromKibana = getKibanaTileMap(); - if (_.get(tilemapSourceFromKibana, 'url')) { - const sourceDescriptor = KibanaTilemapSource.createDescriptor(); - const source = new KibanaTilemapSource(sourceDescriptor); - const layer = source.createDefaultLayer(); - return [layer.toLayerDescriptor(), ...initialLayers]; - } - - const isEmsEnabled = getInjectedVarFunc()('isEmsEnabled', true); - if (isEmsEnabled) { - const descriptor = EMSTMSSource.createDescriptor({ isAutoSelect: true }); - const source = new EMSTMSSource(descriptor); - const layer = source.createDefaultLayer(); - return [layer.toLayerDescriptor(), ...initialLayers]; - } - - return initialLayers; -} diff --git a/x-pack/legacy/plugins/maps/public/angular/map_controller.js b/x-pack/legacy/plugins/maps/public/angular/map_controller.js index 6bc8a4d0be5aca..9522fd12ad37d1 100644 --- a/x-pack/legacy/plugins/maps/public/angular/map_controller.js +++ b/x-pack/legacy/plugins/maps/public/angular/map_controller.js @@ -28,8 +28,10 @@ import { // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { createMapStore } from '../../../../../plugins/maps/public/reducers/store'; import { Provider } from 'react-redux'; -import { GisMap } from '../connected_components/gis_map'; -import { addHelpMenuToAppChrome } from '../help_menu_util'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { GisMap } from '../../../../../plugins/maps/public/connected_components/gis_map'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { addHelpMenuToAppChrome } from '../../../../../plugins/maps/public/help_menu_util'; import { setSelectedLayer, setRefreshConfig, @@ -37,7 +39,8 @@ import { replaceLayerList, setQuery, clearTransientLayerStateAndCloseFlyout, -} from '../actions/map_actions'; + // eslint-disable-next-line @kbn/eslint/no-restricted-paths +} from '../../../../../plugins/maps/public/actions/map_actions'; import { DEFAULT_IS_LAYER_TOC_OPEN, FLYOUT_STATE, @@ -49,22 +52,29 @@ import { setReadOnly, setIsLayerTOCOpen, setOpenTOCDetails, -} from '../actions/ui_actions'; -import { getIsFullScreen } from '../selectors/ui_selectors'; + // eslint-disable-next-line @kbn/eslint/no-restricted-paths +} from '../../../../../plugins/maps/public/actions/ui_actions'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { getIsFullScreen } from '../../../../../plugins/maps/public/selectors/ui_selectors'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { copyPersistentState } from '../../../../../plugins/maps/public/reducers/util'; import { getQueryableUniqueIndexPatternIds, hasDirtyState, getLayerListRaw, -} from '../selectors/map_selectors'; + // eslint-disable-next-line @kbn/eslint/no-restricted-paths +} from '../../../../../plugins/maps/public/selectors/map_selectors'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { getInspectorAdapters } from '../../../../../plugins/maps/public/reducers/non_serializable_instances'; -import { getInitialLayers } from './get_initial_layers'; -import { getInitialQuery } from './get_initial_query'; -import { getInitialTimeFilters } from './get_initial_time_filters'; -import { getInitialRefreshConfig } from './get_initial_refresh_config'; -import { MAP_SAVED_OBJECT_TYPE, MAP_APP_PATH } from '../../common/constants'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { getInitialLayers } from '../../../../../plugins/maps/public/angular/get_initial_layers'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { getInitialQuery } from '../../../../../plugins/maps/public/angular/get_initial_query'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { getInitialTimeFilters } from '../../../../../plugins/maps/public/angular/get_initial_time_filters'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { getInitialRefreshConfig } from '../../../../../plugins/maps/public/angular/get_initial_refresh_config'; +import { MAP_SAVED_OBJECT_TYPE, MAP_APP_PATH } from '../../../../../plugins/maps/common/constants'; import { npSetup, npStart } from 'ui/new_platform'; import { esFilters } from '../../../../../../src/plugins/data/public'; import { diff --git a/x-pack/legacy/plugins/maps/public/components/_index.scss b/x-pack/legacy/plugins/maps/public/components/_index.scss deleted file mode 100644 index 0b327194424244..00000000000000 --- a/x-pack/legacy/plugins/maps/public/components/_index.scss +++ /dev/null @@ -1,3 +0,0 @@ -@import './metric_editors'; -@import './geometry_filter'; -@import './tooltip_selector'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/_index.scss b/x-pack/legacy/plugins/maps/public/connected_components/_index.scss deleted file mode 100644 index 99a2e222ea6c14..00000000000000 --- a/x-pack/legacy/plugins/maps/public/connected_components/_index.scss +++ /dev/null @@ -1,6 +0,0 @@ -@import './gis_map/gis_map'; -@import './layer_addpanel/source_select/index'; -@import './layer_panel/index'; -@import './widget_overlay/index'; -@import './toolbar_overlay/index'; -@import './map/features_tooltip/index'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/source_select/_index.scss b/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/source_select/_index.scss deleted file mode 100644 index 7fe1396fcca16e..00000000000000 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/source_select/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import './source_select'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/_index.scss b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/_index.scss deleted file mode 100644 index fd074edf032fa0..00000000000000 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/_index.scss +++ /dev/null @@ -1,4 +0,0 @@ -@import './layer_panel'; -@import './filter_editor/filter_editor'; -@import './join_editor/resources/join'; -@import './style_settings/style_settings'; \ No newline at end of file diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/view.d.ts b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/view.d.ts deleted file mode 100644 index cf4fdc7be70c68..00000000000000 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/view.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -/* eslint-disable @typescript-eslint/consistent-type-definitions */ - -export * from '../../../../../../plugins/maps/public/connected_components/layer_panel/view'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js deleted file mode 100644 index a1d1341b7c4f7e..00000000000000 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import _ from 'lodash'; -import { - loadSpriteSheetImageData, - addSpriteSheetToMapFromImageData, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../../../plugins/maps/public/connected_components/map/mb/utils'; - -export { loadSpriteSheetImageData, addSpriteSheetToMapFromImageData }; - -export function removeOrphanedSourcesAndLayers(mbMap, layerList) { - const mbStyle = mbMap.getStyle(); - - const mbLayerIdsToRemove = []; - mbStyle.layers.forEach(mbLayer => { - const layer = layerList.find(layer => { - return layer.ownsMbLayerId(mbLayer.id); - }); - if (!layer) { - mbLayerIdsToRemove.push(mbLayer.id); - } - }); - mbLayerIdsToRemove.forEach(mbLayerId => mbMap.removeLayer(mbLayerId)); - - const mbSourcesToRemove = []; - for (const mbSourceId in mbStyle.sources) { - if (mbStyle.sources.hasOwnProperty(mbSourceId)) { - const layer = layerList.find(layer => { - return layer.ownsMbSourceId(mbSourceId); - }); - if (!layer) { - mbSourcesToRemove.push(mbSourceId); - } - } - } - mbSourcesToRemove.forEach(mbSourceId => mbMap.removeSource(mbSourceId)); -} - -/** - * This is function assumes only a single layer moved in the layerList, compared to mbMap - * It is optimized to minimize the amount of mbMap.moveLayer calls. - * @param mbMap - * @param layerList - */ -export function syncLayerOrderForSingleLayer(mbMap, layerList) { - if (!layerList || layerList.length === 0) { - return; - } - - const mbLayers = mbMap.getStyle().layers.slice(); - const layerIds = mbLayers.map(mbLayer => { - const layer = layerList.find(layer => layer.ownsMbLayerId(mbLayer.id)); - return layer.getId(); - }); - - const currentLayerOrderLayerIds = _.uniq(layerIds); - - const newLayerOrderLayerIdsUnfiltered = layerList.map(l => l.getId()); - const newLayerOrderLayerIds = newLayerOrderLayerIdsUnfiltered.filter(layerId => - currentLayerOrderLayerIds.includes(layerId) - ); - - let netPos = 0; - let netNeg = 0; - const movementArr = currentLayerOrderLayerIds.reduce((accu, id, idx) => { - const movement = newLayerOrderLayerIds.findIndex(newOId => newOId === id) - idx; - movement > 0 ? netPos++ : movement < 0 && netNeg++; - accu.push({ id, movement }); - return accu; - }, []); - if (netPos === 0 && netNeg === 0) { - return; - } - const movedLayerId = - (netPos >= netNeg && movementArr.find(l => l.movement < 0).id) || - (netPos < netNeg && movementArr.find(l => l.movement > 0).id); - const nextLayerIdx = newLayerOrderLayerIds.findIndex(layerId => layerId === movedLayerId) + 1; - - let nextMbLayerId; - if (nextLayerIdx === newLayerOrderLayerIds.length) { - nextMbLayerId = null; - } else { - const foundLayer = mbLayers.find(({ id: mbLayerId }) => { - const layerId = newLayerOrderLayerIds[nextLayerIdx]; - const layer = layerList.find(layer => layer.getId() === layerId); - return layer.ownsMbLayerId(mbLayerId); - }); - nextMbLayerId = foundLayer.id; - } - - const movedLayer = layerList.find(layer => layer.getId() === movedLayerId); - mbLayers.forEach(({ id: mbLayerId }) => { - if (movedLayer.ownsMbLayerId(mbLayerId)) { - mbMap.moveLayer(mbLayerId, nextMbLayerId); - } - }); -} - -export async function addSpritesheetToMap(json, imgUrl, mbMap) { - const imgData = await loadSpriteSheetImageData(imgUrl); - addSpriteSheetToMapFromImageData(json, imgData, mbMap); -} diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/_index.scss b/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/_index.scss deleted file mode 100644 index cc1ab35039dac2..00000000000000 --- a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/_index.scss +++ /dev/null @@ -1,6 +0,0 @@ -@import './mixins'; - -@import './widget_overlay'; -@import './attribution_control/attribution_control'; -@import './layer_control/index'; -@import './view_control/view_control'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/_index.scss b/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/_index.scss deleted file mode 100644 index 761ef9d17b4c2d..00000000000000 --- a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/_index.scss +++ /dev/null @@ -1,2 +0,0 @@ -@import './layer_control'; -@import './layer_toc/toc_entry/toc_entry'; diff --git a/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable_factory.ts b/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable_factory.ts index 96c3baf634a834..90b17412377f52 100644 --- a/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable_factory.ts +++ b/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable_factory.ts @@ -4,153 +4,25 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; -import { i18n } from '@kbn/i18n'; +/* + Maintain legacy embeddable legacy present while apps switch over + */ + import { npSetup, npStart } from 'ui/new_platform'; -import { IIndexPattern } from 'src/plugins/data/public'; -// @ts-ignore -import { getMapsSavedObjectLoader } from '../angular/services/gis_map_saved_object_loader'; -import { MapEmbeddable, MapEmbeddableInput } from './map_embeddable'; import { - getIndexPatternService, - getHttp, - getMapsCapabilities, + bindSetupCoreAndPlugins, + bindStartCoreAndPlugins, // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../plugins/maps/public/kibana_services'; -import { - EmbeddableFactoryDefinition, - IContainer, -} from '../../../../../../src/plugins/embeddable/public'; - -import { createMapPath, MAP_SAVED_OBJECT_TYPE, APP_ICON } from '../../common/constants'; +} from '../../../../../plugins/maps/public/plugin'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { createMapStore } from '../../../../../plugins/maps/public/reducers/store'; -import { addLayerWithoutDataSync } from '../actions/map_actions'; -import { getQueryableUniqueIndexPatternIds } from '../selectors/map_selectors'; -import { getInitialLayers } from '../angular/get_initial_layers'; -import { mergeInputWithSavedMap } from './merge_input_with_saved_map'; -import '../angular/services/gis_map_saved_object_loader'; -// @ts-ignore -import { - bindSetupCoreAndPlugins as bindNpSetupCoreAndPlugins, - bindStartCoreAndPlugins as bindNpStartCoreAndPlugins, -} from '../../../../../plugins/maps/public/plugin'; // eslint-disable-line @kbn/eslint/no-restricted-paths - -export class MapEmbeddableFactory implements EmbeddableFactoryDefinition { - type = MAP_SAVED_OBJECT_TYPE; - savedObjectMetaData = { - name: i18n.translate('xpack.maps.mapSavedObjectLabel', { - defaultMessage: 'Map', - }), - type: MAP_SAVED_OBJECT_TYPE, - getIconForSavedObject: () => APP_ICON, - }; - constructor() { - // Init required services. Necessary while in legacy - bindNpSetupCoreAndPlugins(npSetup.core, npSetup.plugins); - bindNpStartCoreAndPlugins(npStart.core, npStart.plugins); - } - - async isEditable() { - return getMapsCapabilities().save as boolean; - } - - // Not supported yet for maps types. - canCreateNew() { - return false; - } - - getDisplayName() { - return i18n.translate('xpack.maps.embeddableDisplayName', { - defaultMessage: 'map', - }); - } - - async _getIndexPatterns(layerList: unknown[]): Promise { - // Need to extract layerList from store to get queryable index pattern ids - const store = createMapStore(); - let queryableIndexPatternIds; - try { - layerList.forEach((layerDescriptor: unknown) => { - store.dispatch(addLayerWithoutDataSync(layerDescriptor)); - }); - queryableIndexPatternIds = getQueryableUniqueIndexPatternIds(store.getState()); - } catch (error) { - throw new Error( - i18n.translate('xpack.maps.mapEmbeddableFactory.invalidLayerList', { - defaultMessage: 'Unable to load map, malformed layer list', - }) - ); - } - - const promises = queryableIndexPatternIds.map(async indexPatternId => { - try { - return await getIndexPatternService().get(indexPatternId); - } catch (error) { - // Unable to load index pattern, better to not throw error so map embeddable can render - // Error will be surfaced by map embeddable since it too will be unable to locate the index pattern - return null; - } - }); - const indexPatterns = await Promise.all(promises); - return _.compact(indexPatterns) as IIndexPattern[]; - } - - async _fetchSavedMap(savedObjectId: string) { - const savedObjectLoader = getMapsSavedObjectLoader(); - return await savedObjectLoader.get(savedObjectId); - } - - createFromSavedObject = async ( - savedObjectId: string, - input: MapEmbeddableInput, - parent?: IContainer - ) => { - const savedMap = await this._fetchSavedMap(savedObjectId); - const layerList = getInitialLayers(savedMap.layerListJSON); - const indexPatterns = await this._getIndexPatterns(layerList); - - const embeddable = new MapEmbeddable( - { - layerList, - title: savedMap.title, - editUrl: getHttp().basePath.prepend(createMapPath(savedObjectId)), - indexPatterns, - editable: await this.isEditable(), - }, - input, - parent - ); - - try { - embeddable.updateInput(mergeInputWithSavedMap(input, savedMap)); - } catch (error) { - throw new Error( - i18n.translate('xpack.maps.mapEmbeddableFactory.invalidSavedObject', { - defaultMessage: 'Unable to load map, malformed saved object', - }) - ); - } - - return embeddable; - }; +import { MAP_SAVED_OBJECT_TYPE } from '../../../../../plugins/maps/common/constants'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { MapEmbeddableFactory } from '../../../../../plugins/maps/public/embeddable'; - create = async (input: MapEmbeddableInput, parent?: IContainer) => { - const layerList = getInitialLayers(); - const indexPatterns = await this._getIndexPatterns(layerList); +bindSetupCoreAndPlugins(npSetup.core, npSetup.plugins); +bindStartCoreAndPlugins(npStart.core, npStart.plugins); - return new MapEmbeddable( - { - layerList, - title: input.title ?? '', - indexPatterns, - editable: false, - }, - input, - parent - ); - }; -} +export * from '../../../../../plugins/maps/public/embeddable/map_embeddable_factory'; npSetup.plugins.embeddable.registerEmbeddableFactory( MAP_SAVED_OBJECT_TYPE, diff --git a/x-pack/legacy/plugins/maps/public/index.scss b/x-pack/legacy/plugins/maps/public/index.scss index b2ac514299d80c..b2a228f01b9210 100644 --- a/x-pack/legacy/plugins/maps/public/index.scss +++ b/x-pack/legacy/plugins/maps/public/index.scss @@ -1,17 +1,3 @@ -// Import the EUI global scope so we can use EUI constants -@import 'src/legacy/ui/public/styles/_styling_constants'; - /* GIS plugin styles */ -// Prefix all styles with "map" to avoid conflicts. -// Examples -// mapChart -// mapChart__legend -// mapChart__legend--small -// mapChart__legend-isLoading - -@import './main'; -@import './mapbox_hacks'; -@import './connected_components/index'; -@import './components/index'; -@import '../../../../plugins/maps/public/layers/index'; +@import '../../../../plugins/maps/public/index'; diff --git a/x-pack/legacy/plugins/maps/public/index.ts b/x-pack/legacy/plugins/maps/public/index.ts index 8555594e909d38..98db26859297b9 100644 --- a/x-pack/legacy/plugins/maps/public/index.ts +++ b/x-pack/legacy/plugins/maps/public/index.ts @@ -15,15 +15,14 @@ import 'uiExports/embeddableActions'; import 'ui/autoload/all'; import 'react-vis/dist/style.css'; - -import './angular/services/gis_map_saved_object_loader'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import '../../../../plugins/maps/public/angular/services/gis_map_saved_object_loader'; import './angular/map_controller'; import './routes'; // @ts-ignore -import { PluginInitializerContext } from 'kibana/public'; import { MapsPlugin } from './plugin'; -export const plugin = (initializerContext: PluginInitializerContext) => { +export const plugin = () => { return new MapsPlugin(); }; @@ -32,4 +31,4 @@ export { RenderTooltipContentParams, ITooltipProperty, } from '../../../../plugins/maps/public/layers/tooltips/tooltip_property'; -export { MapEmbeddable, MapEmbeddableInput } from './embeddable'; +export { MapEmbeddable, MapEmbeddableInput } from '../../../../plugins/maps/public/embeddable'; diff --git a/x-pack/legacy/plugins/maps/public/legacy.ts b/x-pack/legacy/plugins/maps/public/legacy.ts index 96d9e09c1d09a1..bcbfca17755fb4 100644 --- a/x-pack/legacy/plugins/maps/public/legacy.ts +++ b/x-pack/legacy/plugins/maps/public/legacy.ts @@ -7,10 +7,9 @@ import { npSetup, npStart } from 'ui/new_platform'; // @ts-ignore Untyped Module import { uiModules } from 'ui/modules'; -import { PluginInitializerContext } from 'kibana/public'; // eslint-disable-line import/order import { plugin } from '.'; -const pluginInstance = plugin({} as PluginInitializerContext); +const pluginInstance = plugin(); const setupPlugins = { __LEGACY: { diff --git a/x-pack/legacy/plugins/maps/public/plugin.ts b/x-pack/legacy/plugins/maps/public/plugin.ts index 71f1a30c1fbef9..0123e32b6d3b93 100644 --- a/x-pack/legacy/plugins/maps/public/plugin.ts +++ b/x-pack/legacy/plugins/maps/public/plugin.ts @@ -10,7 +10,7 @@ import { Start as InspectorStartContract } from 'src/plugins/inspector/public'; // @ts-ignore import { wrapInI18nContext } from 'ui/i18n'; // @ts-ignore -import { MapListing } from './components/map_listing'; +import { MapListing } from '../../../../plugins/maps/public/components/map_listing'; // eslint-disable-line @kbn/eslint/no-restricted-paths // @ts-ignore import { bindSetupCoreAndPlugins as bindNpSetupCoreAndPlugins, @@ -18,7 +18,6 @@ import { } from '../../../../plugins/maps/public/plugin'; // eslint-disable-line @kbn/eslint/no-restricted-paths import { HomePublicPluginSetup } from '../../../../../src/plugins/home/public'; import { LicensingPluginSetup } from '../../../../plugins/licensing/public'; -import { featureCatalogueEntry } from './feature_catalogue_entry'; import { DataPublicPluginSetup, DataPublicPluginStart, @@ -57,8 +56,6 @@ export class MapsPlugin implements Plugin { }); bindNpSetupCoreAndPlugins(core, np); - - np.home.featureCatalogue.register(featureCatalogueEntry); } public start(core: CoreStart, plugins: MapsPluginStartDependencies) { diff --git a/x-pack/legacy/plugins/maps/public/register_vis_type_alias.js b/x-pack/legacy/plugins/maps/public/register_vis_type_alias.js deleted file mode 100644 index 9dc07bcb5dc0e9..00000000000000 --- a/x-pack/legacy/plugins/maps/public/register_vis_type_alias.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { i18n } from '@kbn/i18n'; -import { APP_ID, APP_ICON, MAP_BASE_URL } from '../common/constants'; -import { - getInjectedVarFunc, - getVisualizations, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../plugins/maps/public/kibana_services'; -import { npSetup } from 'ui/new_platform'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { bindSetupCoreAndPlugins } from '../../../../plugins/maps/public/plugin'; - -bindSetupCoreAndPlugins(npSetup.core, npSetup.plugins); - -const showMapVisualizationTypes = getInjectedVarFunc()('showMapVisualizationTypes', false); - -const description = i18n.translate('xpack.maps.visTypeAlias.description', { - defaultMessage: 'Create and style maps with multiple layers and indices.', -}); - -const legacyMapVisualizationWarning = i18n.translate( - 'xpack.maps.visTypeAlias.legacyMapVizWarning', - { - defaultMessage: `Use the Maps app instead of Coordinate Map and Region Map. -The Maps app offers more functionality and is easier to use.`, - } -); - -getVisualizations().registerAlias({ - aliasUrl: MAP_BASE_URL, - name: APP_ID, - title: i18n.translate('xpack.maps.visTypeAlias.title', { - defaultMessage: 'Maps', - }), - description: showMapVisualizationTypes - ? `${description} ${legacyMapVisualizationWarning}` - : description, - icon: APP_ICON, - stage: 'production', -}); - -if (!showMapVisualizationTypes) { - getVisualizations().hideTypes(['region_map', 'tile_map']); -} diff --git a/x-pack/legacy/plugins/maps/public/routes.js b/x-pack/legacy/plugins/maps/public/routes.js index c082e0e1352c0e..70c1c4a50efd45 100644 --- a/x-pack/legacy/plugins/maps/public/routes.js +++ b/x-pack/legacy/plugins/maps/public/routes.js @@ -6,15 +6,18 @@ import { i18n } from '@kbn/i18n'; import routes from 'ui/routes'; -import listingTemplate from './angular/listing_ng_wrapper.html'; -import mapTemplate from './angular/map.html'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import listingTemplate from '../../../../plugins/maps/public/angular/listing_ng_wrapper.html'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import mapTemplate from '../../../../plugins/maps/public/angular/map.html'; import { getSavedObjectsClient, getCoreChrome, getMapsCapabilities, // eslint-disable-next-line @kbn/eslint/no-restricted-paths } from '../../../../plugins/maps/public/kibana_services'; -import { getMapsSavedObjectLoader } from './angular/services/gis_map_saved_object_loader'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { getMapsSavedObjectLoader } from '../../../../plugins/maps/public/angular/services/gis_map_saved_object_loader'; routes.enable(); diff --git a/x-pack/legacy/plugins/maps/server/lib/get_index_pattern_settings.js b/x-pack/legacy/plugins/maps/server/lib/get_index_pattern_settings.js index c5522b7ba21c58..e2a758075155a5 100644 --- a/x-pack/legacy/plugins/maps/server/lib/get_index_pattern_settings.js +++ b/x-pack/legacy/plugins/maps/server/lib/get_index_pattern_settings.js @@ -5,7 +5,10 @@ */ import _ from 'lodash'; -import { DEFAULT_MAX_RESULT_WINDOW, DEFAULT_MAX_INNER_RESULT_WINDOW } from '../../common/constants'; +import { + DEFAULT_MAX_RESULT_WINDOW, + DEFAULT_MAX_INNER_RESULT_WINDOW, +} from '../../../../../plugins/maps/common/constants'; export function getIndexPatternSettings(indicesSettingsResp) { let maxResultWindow = Infinity; diff --git a/x-pack/legacy/plugins/maps/server/lib/get_index_pattern_settings.test.js b/x-pack/legacy/plugins/maps/server/lib/get_index_pattern_settings.test.js index 01a1ba2703cba3..c152f5bfffc31c 100644 --- a/x-pack/legacy/plugins/maps/server/lib/get_index_pattern_settings.test.js +++ b/x-pack/legacy/plugins/maps/server/lib/get_index_pattern_settings.test.js @@ -5,7 +5,10 @@ */ import { getIndexPatternSettings } from './get_index_pattern_settings'; -import { DEFAULT_MAX_RESULT_WINDOW, DEFAULT_MAX_INNER_RESULT_WINDOW } from '../../common/constants'; +import { + DEFAULT_MAX_RESULT_WINDOW, + DEFAULT_MAX_INNER_RESULT_WINDOW, +} from '../../../../../plugins/maps/common/constants'; describe('max_result_window and max_inner_result_window are not set', () => { test('Should provide default values when values not set', () => { diff --git a/x-pack/legacy/plugins/maps/server/maps_telemetry/collectors/register.ts b/x-pack/legacy/plugins/maps/server/maps_telemetry/collectors/register.ts index 652bb83a0d781c..d34e306d1fff90 100644 --- a/x-pack/legacy/plugins/maps/server/maps_telemetry/collectors/register.ts +++ b/x-pack/legacy/plugins/maps/server/maps_telemetry/collectors/register.ts @@ -9,7 +9,7 @@ import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { SavedObjectsClientContract } from 'src/core/server'; import { getMapsTelemetry } from '../maps_telemetry'; // @ts-ignore -import { TELEMETRY_TYPE } from '../../../common/constants'; +import { TELEMETRY_TYPE } from '../../../../../../plugins/maps/common/constants'; export function registerMapsUsageCollector( usageCollection: UsageCollectionSetup, diff --git a/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.ts b/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.ts index 27c0211446e852..4610baabad3fe5 100644 --- a/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.ts +++ b/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.ts @@ -16,8 +16,8 @@ import { ES_GEO_FIELD_TYPE, MAP_SAVED_OBJECT_TYPE, TELEMETRY_TYPE, -} from '../../common/constants'; -import { LayerDescriptor } from '../../common/descriptor_types'; +} from '../../../../../plugins/maps/common/constants'; +import { LayerDescriptor } from '../../../../../plugins/maps/common/descriptor_types'; import { MapSavedObject } from '../../../../../plugins/maps/common/map_saved_object_type'; interface IStats { diff --git a/x-pack/legacy/plugins/maps/server/plugin.js b/x-pack/legacy/plugins/maps/server/plugin.js index 25c552433e9f82..79f3dcf76b82eb 100644 --- a/x-pack/legacy/plugins/maps/server/plugin.js +++ b/x-pack/legacy/plugins/maps/server/plugin.js @@ -4,7 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ import { i18n } from '@kbn/i18n'; -import { APP_ID, APP_ICON, createMapPath, MAP_SAVED_OBJECT_TYPE } from '../common/constants'; +import { + APP_ID, + APP_ICON, + createMapPath, + MAP_SAVED_OBJECT_TYPE, +} from '../../../../plugins/maps/common/constants'; import { getEcommerceSavedObjects } from './sample_data/ecommerce_saved_objects'; import { getFlightsSavedObjects } from './sample_data/flights_saved_objects.js'; import { getWebLogsSavedObjects } from './sample_data/web_logs_saved_objects.js'; diff --git a/x-pack/legacy/plugins/maps/server/routes.js b/x-pack/legacy/plugins/maps/server/routes.js index 20e022001577a8..d49f9827e3ea04 100644 --- a/x-pack/legacy/plugins/maps/server/routes.js +++ b/x-pack/legacy/plugins/maps/server/routes.js @@ -21,7 +21,7 @@ import { GIS_API_PATH, EMS_SPRITES_PATH, INDEX_SETTINGS_API_PATH, -} from '../common/constants'; +} from '../../../../plugins/maps/common/constants'; import { EMSClient } from '@elastic/ems-client'; import fetch from 'node-fetch'; import { i18n } from '@kbn/i18n'; diff --git a/x-pack/legacy/plugins/reporting/common/constants.ts b/x-pack/legacy/plugins/reporting/common/constants.ts index e3d6a4274e7df7..f30a7cc87f3187 100644 --- a/x-pack/legacy/plugins/reporting/common/constants.ts +++ b/x-pack/legacy/plugins/reporting/common/constants.ts @@ -20,6 +20,7 @@ export const API_GENERATE_IMMEDIATE = `${API_BASE_URL_V1}/generate/immediate/csv export const CONTENT_TYPE_CSV = 'text/csv'; export const CSV_REPORTING_ACTION = 'downloadCsvReport'; export const CSV_BOM_CHARS = '\ufeff'; +export const CSV_FORMULA_CHARS = ['=', '+', '-', '@']; export const WHITELISTED_JOB_CONTENT_TYPES = [ 'application/json', diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.test.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.test.ts index f0afade8629ab4..ad35aaf0030943 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.test.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.test.ts @@ -300,7 +300,7 @@ describe('CSV Execute Job', function() { }); }); - describe('Cells with formula values', () => { + describe('Warning when cells have formulas', () => { it('returns `csv_contains_formulas` when cells contain formulas', async function() { configGetStub.withArgs('csv', 'checkForFormulas').returns(true); callAsCurrentUserStub.onFirstCall().returns({ @@ -353,6 +353,7 @@ describe('CSV Execute Job', function() { it('returns no warnings when cells have no formulas', async function() { configGetStub.withArgs('csv', 'checkForFormulas').returns(true); + configGetStub.withArgs('csv', 'escapeFormulaValues').returns(false); callAsCurrentUserStub.onFirstCall().returns({ hits: { hits: [{ _source: { one: 'foo', two: 'bar' } }], @@ -376,6 +377,33 @@ describe('CSV Execute Job', function() { expect(csvContainsFormulas).toEqual(false); }); + it('returns no warnings when cells have formulas but are escaped', async function() { + configGetStub.withArgs('csv', 'checkForFormulas').returns(true); + configGetStub.withArgs('csv', 'escapeFormulaValues').returns(true); + callAsCurrentUserStub.onFirstCall().returns({ + hits: { + hits: [{ _source: { '=SUM(A1:A2)': 'foo', two: 'bar' } }], + }, + _scroll_id: 'scrollId', + }); + + const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger); + const jobParams = getJobDocPayload({ + headers: encryptedHeaders, + fields: ['=SUM(A1:A2)', 'two'], + conflictedTypesFields: [], + searchRequest: { index: null, body: null }, + }); + + const { csv_contains_formulas: csvContainsFormulas } = await executeJob( + 'job123', + jobParams, + cancellationToken + ); + + expect(csvContainsFormulas).toEqual(false); + }); + it('returns no warnings when configured not to', async () => { configGetStub.withArgs('csv', 'checkForFormulas').returns(false); callAsCurrentUserStub.onFirstCall().returns({ @@ -446,6 +474,50 @@ describe('CSV Execute Job', function() { }); }); + describe('Escaping cells with formulas', () => { + it('escapes values with formulas', async () => { + configGetStub.withArgs('csv', 'escapeFormulaValues').returns(true); + callAsCurrentUserStub.onFirstCall().returns({ + hits: { + hits: [{ _source: { one: `=cmd|' /C calc'!A0`, two: 'bar' } }], + }, + _scroll_id: 'scrollId', + }); + + const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger); + const jobParams = getJobDocPayload({ + headers: encryptedHeaders, + fields: ['one', 'two'], + conflictedTypesFields: [], + searchRequest: { index: null, body: null }, + }); + const { content } = await executeJob('job123', jobParams, cancellationToken); + + expect(content).toEqual("one,two\n\"'=cmd|' /C calc'!A0\",bar\n"); + }); + + it('does not escapes values with formulas', async () => { + configGetStub.withArgs('csv', 'escapeFormulaValues').returns(false); + callAsCurrentUserStub.onFirstCall().returns({ + hits: { + hits: [{ _source: { one: `=cmd|' /C calc'!A0`, two: 'bar' } }], + }, + _scroll_id: 'scrollId', + }); + + const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger); + const jobParams = getJobDocPayload({ + headers: encryptedHeaders, + fields: ['one', 'two'], + conflictedTypesFields: [], + searchRequest: { index: null, body: null }, + }); + const { content } = await executeJob('job123', jobParams, cancellationToken); + + expect(content).toEqual('one,two\n"=cmd|\' /C calc\'!A0",bar\n'); + }); + }); + describe('Elasticsearch call errors', function() { it('should reject Promise if search call errors out', async function() { callAsCurrentUserStub.rejects(new Error()); diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.ts index 376a398da274f9..dbe305bc452dbf 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.ts @@ -123,7 +123,7 @@ export const executeJobFactory: ExecuteJobFactory + CSV_FORMULA_CHARS.some(formulaChar => startsWith(val, formulaChar)); diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/check_cells_for_formulas.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/check_cells_for_formulas.ts index 09f7cd2061ffbb..0ec39c527d6567 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/check_cells_for_formulas.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/check_cells_for_formulas.ts @@ -5,8 +5,7 @@ */ import * as _ from 'lodash'; - -const formulaValues = ['=', '+', '-', '@']; +import { cellHasFormulas } from './cell_has_formula'; interface IFlattened { [header: string]: string; @@ -14,7 +13,7 @@ interface IFlattened { export const checkIfRowsHaveFormulas = (flattened: IFlattened, fields: string[]) => { const pruned = _.pick(flattened, fields); - const csvValues = [..._.keys(pruned), ...(_.values(pruned) as string[])]; + const cells = [..._.keys(pruned), ...(_.values(pruned) as string[])]; - return _.some(csvValues, cell => _.some(formulaValues, char => _.startsWith(cell, char))); + return _.some(cells, cell => cellHasFormulas(cell)); }; diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/escape_value.test.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/escape_value.test.ts index 64b021a2aeea84..dd0f9d08b864b9 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/escape_value.test.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/escape_value.test.ts @@ -11,7 +11,7 @@ describe('escapeValue', function() { describe('quoteValues is true', function() { let escapeValue: (val: string) => string; beforeEach(function() { - escapeValue = createEscapeValue(true); + escapeValue = createEscapeValue(true, false); }); it('should escape value with spaces', function() { @@ -46,7 +46,7 @@ describe('escapeValue', function() { describe('quoteValues is false', function() { let escapeValue: (val: string) => string; beforeEach(function() { - escapeValue = createEscapeValue(false); + escapeValue = createEscapeValue(false, false); }); it('should return the value unescaped', function() { @@ -54,4 +54,34 @@ describe('escapeValue', function() { expect(escapeValue(value)).to.be(value); }); }); + + describe('escapeValues', () => { + describe('when true', () => { + let escapeValue: (val: string) => string; + beforeEach(function() { + escapeValue = createEscapeValue(true, true); + }); + + ['@', '+', '-', '='].forEach(badChar => { + it(`should escape ${badChar} injection values`, function() { + expect(escapeValue(`${badChar}cmd|' /C calc'!A0`)).to.be( + `"'${badChar}cmd|' /C calc'!A0"` + ); + }); + }); + }); + + describe('when false', () => { + let escapeValue: (val: string) => string; + beforeEach(function() { + escapeValue = createEscapeValue(true, false); + }); + + ['@', '+', '-', '='].forEach(badChar => { + it(`should not escape ${badChar} injection values`, function() { + expect(escapeValue(`${badChar}cmd|' /C calc'!A0`)).to.be(`"${badChar}cmd|' /C calc'!A0"`); + }); + }); + }); + }); }); diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/escape_value.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/escape_value.ts index 563de563350e9e..60e75d74b2f98e 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/escape_value.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/escape_value.ts @@ -5,15 +5,20 @@ */ import { RawValue } from './types'; +import { cellHasFormulas } from './cell_has_formula'; const nonAlphaNumRE = /[^a-zA-Z0-9]/; const allDoubleQuoteRE = /"/g; -export function createEscapeValue(quoteValues: boolean): (val: RawValue) => string { +export function createEscapeValue( + quoteValues: boolean, + escapeFormulas: boolean +): (val: RawValue) => string { return function escapeValue(val: RawValue) { if (val && typeof val === 'string') { - if (quoteValues && nonAlphaNumRE.test(val)) { - return `"${val.replace(allDoubleQuoteRE, '""')}"`; + const formulasEscaped = escapeFormulas && cellHasFormulas(val) ? "'" + val : val; + if (quoteValues && nonAlphaNumRE.test(formulasEscaped)) { + return `"${formulasEscaped.replace(allDoubleQuoteRE, '""')}"`; } } diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/generate_csv.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/generate_csv.ts index 1986e68917ba86..c7996ebf832a19 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/generate_csv.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/generate_csv.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { i18n } from '@kbn/i18n'; import { Logger } from '../../../../types'; import { GenerateCsvParams, SavedSearchGeneratorResult } from '../../types'; import { createFlattenHit } from './flatten_hit'; @@ -26,14 +27,17 @@ export function createGenerateCsv(logger: Logger) { cancellationToken, settings, }: GenerateCsvParams): Promise { - const escapeValue = createEscapeValue(settings.quoteValues); + const escapeValue = createEscapeValue(settings.quoteValues, settings.escapeFormulaValues); const builder = new MaxSizeStringBuilder(settings.maxSizeBytes); const header = `${fields.map(escapeValue).join(settings.separator)}\n`; + const warnings: string[] = []; + if (!builder.tryAppend(header)) { return { size: 0, content: '', maxSizeReached: true, + warnings: [], }; } @@ -82,11 +86,20 @@ export function createGenerateCsv(logger: Logger) { const size = builder.getSizeInBytes(); logger.debug(`finished generating, total size in bytes: ${size}`); + if (csvContainsFormulas && settings.escapeFormulaValues) { + warnings.push( + i18n.translate('xpack.reporting.exportTypes.csv.generateCsv.escapedFormulaValues', { + defaultMessage: 'CSV may contain formulas whose values have been escaped', + }) + ); + } + return { content: builder.getString(), - csvContainsFormulas, + csvContainsFormulas: csvContainsFormulas && !settings.escapeFormulaValues, maxSizeReached, size, + warnings, }; }; } diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/types.d.ts b/x-pack/legacy/plugins/reporting/export_types/csv/types.d.ts index 529c195486bc6d..40a42db3526352 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/types.d.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/types.d.ts @@ -87,6 +87,7 @@ export interface SavedSearchGeneratorResult { size: number; maxSizeReached: boolean; csvContainsFormulas?: boolean; + warnings: string[]; } export interface CsvResultFromSearch { @@ -109,5 +110,6 @@ export interface GenerateCsvParams { maxSizeBytes: number; scroll: ScrollConfig; checkForFormulas?: boolean; + escapeFormulaValues: boolean; }; } diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts index 9757c71c19cf41..2611b74c83de92 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts @@ -173,6 +173,7 @@ export async function generateCsvSearch( ...uiSettings, maxSizeBytes: config.get('csv', 'maxSizeBytes'), scroll: config.get('csv', 'scroll'), + escapeFormulaValues: config.get('csv', 'escapeFormulaValues'), timezone, }, }; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.test.tsx index f4955c2a93b8dd..59b3b02ff3587a 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.test.tsx @@ -5,10 +5,138 @@ */ import React from 'react'; -import { shallow } from 'enzyme'; +import { shallow, mount } from 'enzyme'; +import { act } from 'react-dom/test-utils'; +import { createKibanaContextProviderMock } from '../../../../mock/kibana_react'; +import { TestProviders } from '../../../../mock'; +import { wait } from '../../../../lib/helpers'; import { AllRules } from './index'; +jest.mock('./reducer', () => { + return { + allRulesReducer: jest.fn().mockReturnValue(() => ({ + exportRuleIds: [], + filterOptions: { + filter: 'some filter', + sortField: 'some sort field', + sortOrder: 'desc', + }, + loadingRuleIds: [], + loadingRulesAction: null, + pagination: { + page: 1, + perPage: 20, + total: 1, + }, + rules: [ + { + actions: [], + created_at: '2020-02-14T19:49:28.178Z', + created_by: 'elastic', + description: 'jibber jabber', + enabled: false, + false_positives: [], + filters: [], + from: 'now-660s', + id: 'rule-id-1', + immutable: true, + index: ['endgame-*'], + interval: '10m', + language: 'kuery', + max_signals: 100, + name: 'Credential Dumping - Detected - Elastic Endpoint', + output_index: '.siem-signals-default', + query: 'host.name:*', + references: [], + risk_score: 73, + rule_id: '571afc56-5ed9-465d-a2a9-045f099f6e7e', + severity: 'high', + tags: ['Elastic', 'Endpoint'], + threat: [], + throttle: null, + to: 'now', + type: 'query', + updated_at: '2020-02-14T19:49:28.320Z', + updated_by: 'elastic', + version: 1, + }, + ], + selectedRuleIds: [], + })), + }; +}); + +jest.mock('../../../../containers/detection_engine/rules', () => { + return { + useRules: jest.fn().mockReturnValue([ + false, + { + page: 1, + perPage: 20, + total: 1, + data: [ + { + actions: [], + created_at: '2020-02-14T19:49:28.178Z', + created_by: 'elastic', + description: 'jibber jabber', + enabled: false, + false_positives: [], + filters: [], + from: 'now-660s', + id: 'rule-id-1', + immutable: true, + index: ['endgame-*'], + interval: '10m', + language: 'kuery', + max_signals: 100, + name: 'Credential Dumping - Detected - Elastic Endpoint', + output_index: '.siem-signals-default', + query: 'host.name:*', + references: [], + risk_score: 73, + rule_id: '571afc56-5ed9-465d-a2a9-045f099f6e7e', + severity: 'high', + tags: ['Elastic', 'Endpoint'], + threat: [], + throttle: null, + to: 'now', + type: 'query', + updated_at: '2020-02-14T19:49:28.320Z', + updated_by: 'elastic', + version: 1, + }, + ], + }, + ]), + useRulesStatuses: jest.fn().mockReturnValue({ + loading: false, + rulesStatuses: [ + { + current_status: { + alert_id: 'alertId', + bulk_create_time_durations: ['2235.01'], + gap: null, + last_failure_at: null, + last_failure_message: null, + last_look_back_date: new Date().toISOString(), + last_success_at: new Date().toISOString(), + last_success_message: 'it is a success', + search_after_time_durations: ['616.97'], + status: 'succeeded', + status_date: new Date().toISOString(), + }, + failures: [], + id: '12345678987654321', + activate: true, + name: 'Test rule', + }, + ], + }), + }; +}); + jest.mock('react-router-dom', () => { const originalModule = jest.requireActual('react-router-dom'); @@ -37,4 +165,66 @@ describe('AllRules', () => { expect(wrapper.find('[title="All rules"]')).toHaveLength(1); }); + + it('renders rules tab', async () => { + const KibanaContext = createKibanaContextProviderMock(); + const wrapper = mount( + + + + + + ); + + await act(async () => { + await wait(); + + expect(wrapper.exists('[data-test-subj="monitoring-table"]')).toBeFalsy(); + expect(wrapper.exists('[data-test-subj="rules-table"]')).toBeTruthy(); + }); + }); + + it('renders monitoring tab when monitoring tab clicked', async () => { + const KibanaContext = createKibanaContextProviderMock(); + + const wrapper = mount( + + + + + + ); + const monitoringTab = wrapper.find('[data-test-subj="allRulesTableTab-monitoring"] button'); + monitoringTab.simulate('click'); + + await act(async () => { + wrapper.update(); + await wait(); + + expect(wrapper.exists('[data-test-subj="monitoring-table"]')).toBeTruthy(); + expect(wrapper.exists('[data-test-subj="rules-table"]')).toBeFalsy(); + }); + }); }); diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.tsx index e96ed856208bde..18ca4d42bd018d 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.tsx @@ -4,7 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiBasicTable, EuiContextMenuPanel, EuiLoadingContent, EuiSpacer } from '@elastic/eui'; +import { + EuiBasicTable, + EuiContextMenuPanel, + EuiLoadingContent, + EuiSpacer, + EuiTab, + EuiTabs, +} from '@elastic/eui'; import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react'; import { useHistory } from 'react-router-dom'; import uuid from 'uuid'; @@ -75,6 +82,24 @@ interface AllRulesProps { setRefreshRulesData: (refreshRule: (refreshPrePackagedRule?: boolean) => void) => void; } +export enum AllRulesTabs { + rules = 'rules', + monitoring = 'monitoring', +} + +const allRulesTabs = [ + { + id: AllRulesTabs.rules, + name: i18n.RULES_TAB, + disabled: false, + }, + { + id: AllRulesTabs.monitoring, + name: i18n.MONITORING_TAB, + disabled: false, + }, +]; + /** * Table Component for displaying all Rules for a given cluster. Provides the ability to filter * by name, sort by enabled, and perform the following actions: @@ -114,6 +139,7 @@ export const AllRules = React.memo( const history = useHistory(); const [, dispatchToaster] = useStateToaster(); const mlCapabilities = useMlCapabilities(); + const [allRulesTab, setAllRulesTab] = useState(AllRulesTabs.rules); // TODO: Refactor license check + hasMlAdminPermissions to common check const hasMlPermissions = @@ -271,6 +297,25 @@ export const AllRules = React.memo( return false; }, [loadingRuleIds, loadingRulesAction]); + const tabs = useMemo( + () => ( + + {allRulesTabs.map(tab => ( + setAllRulesTab(tab.id)} + isSelected={tab.id === allRulesTab} + disabled={tab.disabled} + key={tab.id} + > + {tab.name} + + ))} + + ), + [allRulesTabs, allRulesTab, setAllRulesTab] + ); + return ( <> ( exportSelectedData={exportRules} /> + {tabs} + <> @@ -321,7 +368,7 @@ export const AllRules = React.memo( )} {showRulesTable({ rulesCustomInstalled, rulesInstalled }) && !initLoading && ( <> - + @@ -352,6 +399,7 @@ export const AllRules = React.memo( { it('renders correctly', () => { @@ -16,6 +17,7 @@ describe('AllRulesTables', () => { return ( { expect(wrapper.dive().find('[data-test-subj="rules-table"]')).toHaveLength(1); }); + + it('renders rules tab when "selectedTab" is "rules"', () => { + const Component = () => { + const ref = useRef(); + + return ( + + ); + }; + const wrapper = shallow(); + + expect(wrapper.dive().find('[data-test-subj="rules-table"]')).toHaveLength(1); + expect(wrapper.dive().find('[data-test-subj="monitoring-table"]')).toHaveLength(0); + }); + + it('renders monitoring tab when "selectedTab" is "monitoring"', () => { + const Component = () => { + const ref = useRef(); + + return ( + + ); + }; + const wrapper = shallow(); + + expect(wrapper.dive().find('[data-test-subj="rules-table"]')).toHaveLength(0); + expect(wrapper.dive().find('[data-test-subj="monitoring-table"]')).toHaveLength(1); + }); }); diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/all_rules_tables/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/all_rules_tables/index.tsx index 31aaa426e4f3b8..8ea5606d0082c0 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/all_rules_tables/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/all_rules_tables/index.tsx @@ -7,13 +7,11 @@ import { EuiBasicTable, EuiBasicTableColumn, - EuiTab, - EuiTabs, EuiEmptyPrompt, Direction, EuiTableSelectionType, } from '@elastic/eui'; -import React, { useMemo, memo, useState } from 'react'; +import React, { useMemo, memo } from 'react'; import styled from 'styled-components'; import { EuiBasicTableOnChange } from '../../types'; @@ -23,6 +21,7 @@ import { RuleStatusRowItemType, } from '../../../../../pages/detection_engine/rules/all/columns'; import { Rule, Rules } from '../../../../../containers/detection_engine/rules'; +import { AllRulesTabs } from '../../all'; // EuiBasicTable give me a hardtime with adding the ref attributes so I went the easy way // after few hours of fight with typescript !!!! I lost :( @@ -57,27 +56,10 @@ interface AllRulesTablesProps { }; tableOnChangeCallback: ({ page, sort }: EuiBasicTableOnChange) => void; tableRef?: React.MutableRefObject; + selectedTab: AllRulesTabs; } -enum AllRulesTabs { - rules = 'rules', - monitoring = 'monitoring', -} - -const allRulesTabs = [ - { - id: AllRulesTabs.rules, - name: i18n.RULES_TAB, - disabled: false, - }, - { - id: AllRulesTabs.monitoring, - name: i18n.MONITORING_TAB, - disabled: false, - }, -]; - -const AllRulesTablesComponent: React.FC = ({ +export const AllRulesTablesComponent: React.FC = ({ euiBasicTableSelectionProps, hasNoPermissions, monitoringColumns, @@ -88,34 +70,17 @@ const AllRulesTablesComponent: React.FC = ({ sorting, tableOnChangeCallback, tableRef, + selectedTab, }) => { - const [allRulesTab, setAllRulesTab] = useState(AllRulesTabs.rules); const emptyPrompt = useMemo(() => { return ( {i18n.NO_RULES}} titleSize="xs" body={i18n.NO_RULES_BODY} /> ); }, []); - const tabs = useMemo( - () => ( - - {allRulesTabs.map(tab => ( - setAllRulesTab(tab.id)} - isSelected={tab.id === allRulesTab} - disabled={tab.disabled} - key={tab.id} - > - {tab.name} - - ))} - - ), - [allRulesTabs, allRulesTab, setAllRulesTab] - ); + return ( <> - {tabs} - {allRulesTab === AllRulesTabs.rules && ( + {selectedTab === AllRulesTabs.rules && ( = ({ selection={hasNoPermissions ? undefined : euiBasicTableSelectionProps} /> )} - {allRulesTab === AllRulesTabs.monitoring && ( + {selectedTab === AllRulesTabs.monitoring && ( ; -export type CheckGeo = t.TypeOf; export type Location = t.TypeOf; export type StatesIndexStatus = t.TypeOf; export type DateRange = t.TypeOf; diff --git a/x-pack/legacy/plugins/uptime/common/types/index.ts b/x-pack/legacy/plugins/uptime/common/types/index.ts index fcbb92caf26d5b..a32eabd49a3e5e 100644 --- a/x-pack/legacy/plugins/uptime/common/types/index.ts +++ b/x-pack/legacy/plugins/uptime/common/types/index.ts @@ -35,3 +35,7 @@ export interface MonitorDurationResult { /** The average values for the monitor duration. */ locationDurationLines: LocationDurationLine[]; } + +export interface MonitorIdParam { + monitorId: string; +} diff --git a/x-pack/legacy/plugins/uptime/public/apps/plugin.ts b/x-pack/legacy/plugins/uptime/public/apps/plugin.ts index eec49418910f8b..e73598c44c9f08 100644 --- a/x-pack/legacy/plugins/uptime/public/apps/plugin.ts +++ b/x-pack/legacy/plugins/uptime/public/apps/plugin.ts @@ -4,23 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - LegacyCoreStart, - LegacyCoreSetup, - PluginInitializerContext, - AppMountParameters, -} from 'src/core/public'; -import { PluginsStart, PluginsSetup } from 'ui/new_platform/new_platform'; +import { LegacyCoreSetup, PluginInitializerContext, AppMountParameters } from 'src/core/public'; +import { PluginsSetup } from 'ui/new_platform/new_platform'; import { FeatureCatalogueCategory } from '../../../../../../src/plugins/home/public'; import { UMFrontendLibs } from '../lib/lib'; import { PLUGIN } from '../../common/constants'; import { getKibanaFrameworkAdapter } from '../lib/adapters/framework/new_platform_adapter'; -export interface StartObject { - core: LegacyCoreStart; - plugins: PluginsStart; -} - export interface SetupObject { core: LegacyCoreSetup; plugins: PluginsSetup; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/location_link.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/common/__tests__/__snapshots__/location_link.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/location_link.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/common/__tests__/__snapshots__/location_link.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/uptime_date_picker.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/common/__tests__/__snapshots__/uptime_date_picker.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/uptime_date_picker.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/common/__tests__/__snapshots__/uptime_date_picker.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/location_link.test.tsx b/x-pack/legacy/plugins/uptime/public/components/common/__tests__/location_link.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/location_link.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/__tests__/location_link.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/uptime_date_picker.test.tsx b/x-pack/legacy/plugins/uptime/public/components/common/__tests__/uptime_date_picker.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/__tests__/uptime_date_picker.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/__tests__/uptime_date_picker.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/__snapshots__/chart_empty_state.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_empty_state.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/__snapshots__/chart_empty_state.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_empty_state.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/__snapshots__/chart_wrapper.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_wrapper.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/__snapshots__/chart_wrapper.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_wrapper.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/__snapshots__/donut_chart.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/__snapshots__/donut_chart.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/__snapshots__/donut_chart_legend.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart_legend.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/__snapshots__/donut_chart_legend.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart_legend.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/__snapshots__/donut_chart_legend_row.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart_legend_row.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/__snapshots__/donut_chart_legend_row.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart_legend_row.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/__snapshots__/duration_charts.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/duration_charts.test.tsx.snap similarity index 99% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/__snapshots__/duration_charts.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/duration_charts.test.tsx.snap index 6c38f3e338cfd2..96918ab68f7163 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/__snapshots__/duration_charts.test.tsx.snap +++ b/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/duration_charts.test.tsx.snap @@ -53,7 +53,6 @@ exports[`MonitorCharts component renders the component without errors 1`] = ` > { const component = shallowWithRouter( diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/get_tick_format.test.ts b/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/get_tick_format.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/get_tick_format.test.ts rename to x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/get_tick_format.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/monitor_bar_series.test.tsx b/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/monitor_bar_series.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/monitor_bar_series.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/monitor_bar_series.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/ping_histogram.test.tsx b/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/ping_histogram.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/ping_histogram.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/ping_histogram.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/annotation_tooltip.tsx b/x-pack/legacy/plugins/uptime/public/components/common/charts/annotation_tooltip.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/annotation_tooltip.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/charts/annotation_tooltip.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/chart_empty_state.tsx b/x-pack/legacy/plugins/uptime/public/components/common/charts/chart_empty_state.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/chart_empty_state.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/charts/chart_empty_state.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/chart_wrapper/chart_wrapper.tsx b/x-pack/legacy/plugins/uptime/public/components/common/charts/chart_wrapper/chart_wrapper.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/chart_wrapper/chart_wrapper.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/charts/chart_wrapper/chart_wrapper.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/chart_wrapper/index.ts b/x-pack/legacy/plugins/uptime/public/components/common/charts/chart_wrapper/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/chart_wrapper/index.ts rename to x-pack/legacy/plugins/uptime/public/components/common/charts/chart_wrapper/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart.tsx b/x-pack/legacy/plugins/uptime/public/components/common/charts/donut_chart.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/charts/donut_chart.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart_legend.tsx b/x-pack/legacy/plugins/uptime/public/components/common/charts/donut_chart_legend.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart_legend.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/charts/donut_chart_legend.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart_legend_row.tsx b/x-pack/legacy/plugins/uptime/public/components/common/charts/donut_chart_legend_row.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart_legend_row.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/charts/donut_chart_legend_row.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/duration_chart.tsx b/x-pack/legacy/plugins/uptime/public/components/common/charts/duration_chart.tsx new file mode 100644 index 00000000000000..c82b2a1cf9fe2b --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/common/charts/duration_chart.tsx @@ -0,0 +1,122 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useState } from 'react'; +import { i18n } from '@kbn/i18n'; +import moment from 'moment'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { Axis, Chart, Position, timeFormatter, Settings, SeriesIdentifier } from '@elastic/charts'; +import { getChartDateLabel } from '../../../lib/helper'; +import { LocationDurationLine } from '../../../../common/types'; +import { DurationLineSeriesList } from './duration_line_series_list'; +import { ChartWrapper } from './chart_wrapper'; +import { useUrlParams } from '../../../hooks'; +import { getTickFormat } from './get_tick_format'; +import { ChartEmptyState } from './chart_empty_state'; +import { DurationAnomaliesBar } from './duration_line_bar_list'; +import { AnomalyRecords } from '../../../state/actions'; + +interface DurationChartProps { + /** + * Timeseries data that is used to express an average line series + * on the duration chart. One entry per location + */ + locationDurationLines: LocationDurationLine[]; + + /** + * To represent the loading spinner on chart + */ + loading: boolean; + + anomalies: AnomalyRecords | null; +} + +/** + * This chart is intended to visualize monitor duration performance over time to + * the users in a helpful way. Its x-axis is based on a timeseries, the y-axis is in + * milliseconds. + * @param props The props required for this component to render properly + */ +export const DurationChartComponent = ({ + locationDurationLines, + anomalies, + loading, +}: DurationChartProps) => { + const hasLines = locationDurationLines.length > 0; + const [getUrlParams, updateUrlParams] = useUrlParams(); + const { absoluteDateRangeStart: min, absoluteDateRangeEnd: max } = getUrlParams(); + + const [hiddenLegends, setHiddenLegends] = useState([]); + + const onBrushEnd = (minX: number, maxX: number) => { + updateUrlParams({ + dateRangeStart: moment(minX).toISOString(), + dateRangeEnd: moment(maxX).toISOString(), + }); + }; + + const legendToggleVisibility = (legendItem: SeriesIdentifier | null) => { + if (legendItem) { + setHiddenLegends(prevState => { + if (prevState.includes(legendItem.specId)) { + return [...prevState.filter(item => item !== legendItem.specId)]; + } else { + return [...prevState, legendItem.specId]; + } + }); + } + }; + + return ( + + {hasLines ? ( + + + + getTickFormat(d)} + title={i18n.translate('xpack.uptime.monitorCharts.durationChart.leftAxis.title', { + defaultMessage: 'Duration ms', + })} + /> + + + + ) : ( + up }} + /> + } + title={i18n.translate('xpack.uptime.durationChart.emptyPrompt.title', { + defaultMessage: 'No duration data available', + })} + /> + )} + + ); +}; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/duration_line_bar_list.tsx b/x-pack/legacy/plugins/uptime/public/components/common/charts/duration_line_bar_list.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/duration_line_bar_list.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/charts/duration_line_bar_list.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/duration_line_series_list.tsx b/x-pack/legacy/plugins/uptime/public/components/common/charts/duration_line_series_list.tsx similarity index 97% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/duration_line_series_list.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/charts/duration_line_series_list.tsx index 912bc5bb0501b5..4223e918393b61 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/charts/duration_line_series_list.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/common/charts/duration_line_series_list.tsx @@ -21,7 +21,7 @@ export const DurationLineSeriesList = ({ lines }: Props) => ( // this id is used for the line chart representing the average duration length data={line.map(({ x, y }) => [x, microsToMillis(y || null)])} id={`loc-avg-${name}`} - key={`locline-${name}`} + key={`loc-line-${name}`} name={name} xAccessor={0} xScaleType="time" diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/get_tick_format.ts b/x-pack/legacy/plugins/uptime/public/components/common/charts/get_tick_format.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/get_tick_format.ts rename to x-pack/legacy/plugins/uptime/public/components/common/charts/get_tick_format.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/index.ts b/x-pack/legacy/plugins/uptime/public/components/common/charts/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/index.ts rename to x-pack/legacy/plugins/uptime/public/components/common/charts/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/monitor_bar_series.tsx b/x-pack/legacy/plugins/uptime/public/components/common/charts/monitor_bar_series.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/monitor_bar_series.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/charts/monitor_bar_series.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/ping_histogram.tsx b/x-pack/legacy/plugins/uptime/public/components/common/charts/ping_histogram.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/charts/ping_histogram.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/charts/ping_histogram.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/higher_order/__tests__/__snapshots__/responsive_wrapper.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/common/higher_order/__tests__/__snapshots__/responsive_wrapper.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/higher_order/__tests__/__snapshots__/responsive_wrapper.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/common/higher_order/__tests__/__snapshots__/responsive_wrapper.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/higher_order/__tests__/responsive_wrapper.test.tsx b/x-pack/legacy/plugins/uptime/public/components/common/higher_order/__tests__/responsive_wrapper.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/higher_order/__tests__/responsive_wrapper.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/higher_order/__tests__/responsive_wrapper.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/higher_order/index.ts b/x-pack/legacy/plugins/uptime/public/components/common/higher_order/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/higher_order/index.ts rename to x-pack/legacy/plugins/uptime/public/components/common/higher_order/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/higher_order/responsive_wrapper.tsx b/x-pack/legacy/plugins/uptime/public/components/common/higher_order/responsive_wrapper.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/higher_order/responsive_wrapper.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/higher_order/responsive_wrapper.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/location_link.tsx b/x-pack/legacy/plugins/uptime/public/components/common/location_link.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/location_link.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/location_link.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/uptime_date_picker.tsx b/x-pack/legacy/plugins/uptime/public/components/common/uptime_date_picker.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/uptime_date_picker.tsx rename to x-pack/legacy/plugins/uptime/public/components/common/uptime_date_picker.tsx index 7d2123af8ff9cd..4254004dba4e0a 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/uptime_date_picker.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/common/uptime_date_picker.tsx @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiSuperDatePicker } from '@elastic/eui'; import React, { useContext } from 'react'; +import { EuiSuperDatePicker } from '@elastic/eui'; import { useUrlParams } from '../../hooks'; import { CLIENT_DEFAULTS } from '../../../common/constants'; import { UptimeRefreshContext, UptimeSettingsContext } from '../../contexts'; diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/charts/ping_histogram.tsx b/x-pack/legacy/plugins/uptime/public/components/connected/charts/ping_histogram.tsx deleted file mode 100644 index cf35dbf4e5206e..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/components/connected/charts/ping_histogram.tsx +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React, { useEffect } from 'react'; -import { connect } from 'react-redux'; -import { AppState } from '../../../state'; -import { - PingHistogramComponent, - PingHistogramComponentProps, -} from '../../functional/charts/ping_histogram'; -import { getPingHistogram } from '../../../state/actions'; -import { selectPingHistogram } from '../../../state/selectors'; -import { withResponsiveWrapper, ResponsiveWrapperProps } from '../../higher_order'; -import { GetPingHistogramParams, HistogramResult } from '../../../../common/runtime_types'; -import { useGetUrlParams } from '../../../hooks'; - -type Props = ResponsiveWrapperProps & - Pick & - DispatchProps & { lastRefresh: number; monitorId?: string; esKuery?: string }; - -const PingHistogramContainer: React.FC = ({ - data, - loadData, - monitorId, - lastRefresh, - height, - loading, - esKuery, -}) => { - const { - absoluteDateRangeStart, - absoluteDateRangeEnd, - dateRangeStart: dateStart, - dateRangeEnd: dateEnd, - statusFilter, - } = useGetUrlParams(); - - useEffect(() => { - loadData({ monitorId, dateStart, dateEnd, statusFilter, filters: esKuery }); - }, [loadData, dateStart, dateEnd, monitorId, statusFilter, lastRefresh, esKuery]); - return ( - - ); -}; - -interface StateProps { - data: HistogramResult | null; - loading: boolean; - lastRefresh: number; - esKuery: string; -} - -interface DispatchProps { - loadData: typeof getPingHistogram; -} - -const mapStateToProps = (state: AppState): StateProps => ({ ...selectPingHistogram(state) }); - -const mapDispatchToProps = (dispatch: any): DispatchProps => ({ - loadData: (params: GetPingHistogramParams) => { - return dispatch(getPingHistogram(params)); - }, -}); - -export const PingHistogram = connect< - StateProps, - DispatchProps, - Pick, - AppState ->( - mapStateToProps, - mapDispatchToProps -)(withResponsiveWrapper(PingHistogramContainer)); diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/charts/snapshot_container.tsx b/x-pack/legacy/plugins/uptime/public/components/connected/charts/snapshot_container.tsx deleted file mode 100644 index 39ead242527f8e..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/components/connected/charts/snapshot_container.tsx +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React, { useEffect } from 'react'; -import { connect } from 'react-redux'; -import { useGetUrlParams } from '../../../hooks'; -import { AppState } from '../../../state'; -import { getSnapshotCountAction } from '../../../state/actions'; -import { SnapshotComponent } from '../../functional/snapshot'; -import { Snapshot as SnapshotType } from '../../../../common/runtime_types'; -import { SnapShotQueryParams } from '../../../state/api'; - -/** - * Props expected from parent components. - */ -interface OwnProps { - /** - * Height is needed, since by default charts takes height of 100% - */ - height?: string; -} - -/** - * Props given by the Redux store based on action input. - */ -interface StoreProps { - count: SnapshotType; - lastRefresh: number; - loading: boolean; - esKuery: string; -} - -/** - * Contains functions that will dispatch actions used - * for this component's life cycle - */ -interface DispatchProps { - loadSnapshotCount: typeof getSnapshotCountAction; -} - -/** - * Props used to render the Snapshot component. - */ -type Props = OwnProps & StoreProps & DispatchProps; - -export const Container: React.FC = ({ - count, - height, - lastRefresh, - loading, - esKuery, - loadSnapshotCount, -}: Props) => { - const { dateRangeStart, dateRangeEnd, statusFilter } = useGetUrlParams(); - - useEffect(() => { - loadSnapshotCount({ dateRangeStart, dateRangeEnd, filters: esKuery, statusFilter }); - }, [dateRangeStart, dateRangeEnd, esKuery, lastRefresh, loadSnapshotCount, statusFilter]); - return ; -}; - -/** - * Provides state to connected component. - * @param state the root app state - */ -const mapStateToProps = ({ - snapshot: { count, loading }, - ui: { lastRefresh, esKuery }, -}: AppState): StoreProps => ({ - count, - lastRefresh, - loading, - esKuery, -}); - -/** - * Used for fetching snapshot counts. - * @param dispatch redux-provided action dispatcher - */ -const mapDispatchToProps = (dispatch: any) => ({ - loadSnapshotCount: (params: SnapShotQueryParams): DispatchProps => { - return dispatch(getSnapshotCountAction(params)); - }, -}); - -export const Snapshot = connect( - // @ts-ignore connect is expecting null | undefined for some reason - mapStateToProps, - mapDispatchToProps -)(Container); diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/index.ts b/x-pack/legacy/plugins/uptime/public/components/connected/index.ts deleted file mode 100644 index 94e2529a46a00d..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/components/connected/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { AlertMonitorStatus, ToggleAlertFlyoutButton, UptimeAlertsFlyoutWrapper } from './alerts'; -export { PingHistogram } from './charts/ping_histogram'; -export { Snapshot } from './charts/snapshot_container'; -export { KueryBar } from './kuerybar/kuery_bar_container'; -export { FilterGroup } from './filter_group/filter_group_container'; -export { MonitorStatusDetails } from './monitor/status_details_container'; -export { MonitorStatusBar } from './monitor/status_bar_container'; -export { MonitorList } from './monitor/monitor_list'; -export { MonitorListDrawer } from './monitor/list_drawer_container'; -export { MonitorListActionsPopover } from './monitor/drawer_popover_container'; -export { PingList, PingListProps } from './pings'; -export { DurationChart } from './charts/monitor_duration'; -export { EmptyState } from './empty_state/empty_state'; diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/monitor/status_bar_container.tsx b/x-pack/legacy/plugins/uptime/public/components/connected/monitor/status_bar_container.tsx deleted file mode 100644 index 3a96aa7c0275b7..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/components/connected/monitor/status_bar_container.tsx +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React, { useContext, useEffect } from 'react'; -import { connect } from 'react-redux'; -import { Dispatch } from 'redux'; -import { AppState } from '../../../state'; -import { monitorLocationsSelector, monitorStatusSelector } from '../../../state/selectors'; -import { MonitorStatusBarComponent } from '../../functional/monitor_status_details/monitor_status_bar'; -import { getMonitorStatusAction } from '../../../state/actions'; -import { useGetUrlParams } from '../../../hooks'; -import { Ping } from '../../../../common/runtime_types'; -import { MonitorLocations } from '../../../../common/runtime_types/monitor'; -import { UptimeRefreshContext } from '../../../contexts'; - -interface StateProps { - monitorStatus: Ping; - monitorLocations: MonitorLocations; -} - -interface DispatchProps { - loadMonitorStatus: typeof getMonitorStatusAction; -} - -interface OwnProps { - monitorId: string; -} - -type Props = OwnProps & StateProps & DispatchProps; - -const Container: React.FC = ({ - loadMonitorStatus, - monitorId, - monitorStatus, - monitorLocations, -}: Props) => { - const { lastRefresh } = useContext(UptimeRefreshContext); - - const { dateRangeStart: dateStart, dateRangeEnd: dateEnd } = useGetUrlParams(); - - useEffect(() => { - loadMonitorStatus({ dateStart, dateEnd, monitorId }); - }, [monitorId, dateStart, dateEnd, loadMonitorStatus, lastRefresh]); - - return ( - - ); -}; - -const mapStateToProps = (state: AppState, ownProps: OwnProps) => ({ - monitorStatus: monitorStatusSelector(state), - monitorLocations: monitorLocationsSelector(state, ownProps.monitorId), -}); - -const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => ({ - loadMonitorStatus: params => dispatch(getMonitorStatusAction(params)), -}); - -// @ts-ignore TODO: Investigate typescript issues here -export const MonitorStatusBar = connect( - // @ts-ignore TODO: Investigate typescript issues here - mapStateToProps, - mapDispatchToProps -)(Container); diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/monitor/status_details_container.tsx b/x-pack/legacy/plugins/uptime/public/components/connected/monitor/status_details_container.tsx deleted file mode 100644 index 9d2e48830fbfe7..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/components/connected/monitor/status_details_container.tsx +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React, { useContext, useEffect } from 'react'; -import { connect } from 'react-redux'; -import { Dispatch } from 'redux'; -import { useGetUrlParams } from '../../../hooks'; -import { AppState } from '../../../state'; -import { monitorLocationsSelector } from '../../../state/selectors'; -import { getMonitorLocationsAction, MonitorLocationsPayload } from '../../../state/actions/monitor'; -import { MonitorStatusDetailsComponent } from '../../functional/monitor_status_details'; -import { MonitorLocations } from '../../../../common/runtime_types'; -import { UptimeRefreshContext } from '../../../contexts'; - -interface OwnProps { - monitorId: string; -} - -interface StoreProps { - monitorLocations: MonitorLocations; -} - -interface DispatchProps { - loadMonitorLocations: typeof getMonitorLocationsAction; -} - -type Props = OwnProps & StoreProps & DispatchProps; - -export const Container: React.FC = ({ - loadMonitorLocations, - monitorLocations, - monitorId, -}: Props) => { - const { lastRefresh } = useContext(UptimeRefreshContext); - - const { dateRangeStart: dateStart, dateRangeEnd: dateEnd } = useGetUrlParams(); - - useEffect(() => { - loadMonitorLocations({ dateStart, dateEnd, monitorId }); - }, [loadMonitorLocations, monitorId, dateStart, dateEnd, lastRefresh]); - - return ( - - ); -}; -const mapStateToProps = (state: AppState, { monitorId }: OwnProps) => ({ - monitorLocations: monitorLocationsSelector(state, monitorId), -}); - -const mapDispatchToProps = (dispatch: Dispatch) => ({ - loadMonitorLocations: (params: MonitorLocationsPayload) => { - dispatch(getMonitorLocationsAction(params)); - }, -}); - -export const MonitorStatusDetails = connect( - // @ts-ignore TODO: Investigate typescript issues here - mapStateToProps, - mapDispatchToProps -)(Container); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/duration_chart.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/charts/duration_chart.tsx deleted file mode 100644 index ec2081d7155542..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/components/functional/charts/duration_chart.tsx +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React, { useState } from 'react'; -import { i18n } from '@kbn/i18n'; -import moment from 'moment'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle } from '@elastic/eui'; -import { Axis, Chart, Position, timeFormatter, Settings, SeriesIdentifier } from '@elastic/charts'; -import { getChartDateLabel } from '../../../lib/helper'; -import { LocationDurationLine } from '../../../../common/types'; -import { DurationLineSeriesList } from './duration_line_series_list'; -import { ChartWrapper } from './chart_wrapper'; -import { useUrlParams } from '../../../hooks'; -import { getTickFormat } from './get_tick_format'; -import { ChartEmptyState } from './chart_empty_state'; -import { DurationAnomaliesBar } from './duration_line_bar_list'; -import { MLIntegrationComponent } from '../../monitor_details/ml/ml_integeration'; -import { AnomalyRecords } from '../../../state/actions'; - -interface DurationChartProps { - /** - * Timeseries data that is used to express an average line series - * on the duration chart. One entry per location - */ - locationDurationLines: LocationDurationLine[]; - - /** - * To represent the loading spinner on chart - */ - loading: boolean; - - hasMLJob: boolean; - - anomalies: AnomalyRecords | null; -} - -/** - * This chart is intended to visualize monitor duration performance over time to - * the users in a helpful way. Its x-axis is based on a timeseries, the y-axis is in - * milliseconds. - * @param props The props required for this component to render properly - */ -export const DurationChartComponent = ({ - locationDurationLines, - anomalies, - loading, - hasMLJob, -}: DurationChartProps) => { - const hasLines = locationDurationLines.length > 0; - const [getUrlParams, updateUrlParams] = useUrlParams(); - const { absoluteDateRangeStart: min, absoluteDateRangeEnd: max } = getUrlParams(); - - const [hiddenLegends, setHiddenLegends] = useState([]); - - const onBrushEnd = (minX: number, maxX: number) => { - updateUrlParams({ - dateRangeStart: moment(minX).toISOString(), - dateRangeEnd: moment(maxX).toISOString(), - }); - }; - - const legendToggleVisibility = (legendItem: SeriesIdentifier | null) => { - if (legendItem) { - setHiddenLegends(prevState => { - if (prevState.includes(legendItem.specId)) { - return [...prevState.filter(item => item !== legendItem.specId)]; - } else { - return [...prevState, legendItem.specId]; - } - }); - } - }; - - return ( - <> - - - - -

- {hasMLJob ? ( - - ) : ( - - )} -

-
-
- - - -
- - - {hasLines ? ( - - - - getTickFormat(d)} - title={i18n.translate('xpack.uptime.monitorCharts.durationChart.leftAxis.title', { - defaultMessage: 'Duration ms', - })} - /> - - - - ) : ( - up }} - /> - } - title={i18n.translate('xpack.uptime.durationChart.emptyPrompt.title', { - defaultMessage: 'No duration data available', - })} - /> - )} - -
- - ); -}; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/index.ts b/x-pack/legacy/plugins/uptime/public/components/functional/index.ts deleted file mode 100644 index 07809561c31b7c..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/components/functional/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { - ToggleAlertFlyoutButtonComponent, - UptimeAlertsContextProvider, - UptimeAlertsFlyoutWrapperComponent, -} from './alerts'; -export * from './alerts'; -export { DonutChart } from './charts/donut_chart'; -export { KueryBarComponent } from './kuery_bar/kuery_bar'; -export { MonitorCharts } from './monitor_charts'; -export { MonitorListComponent } from './monitor_list'; -export { OverviewPageParsingErrorCallout } from './overview_page_parsing_error_callout'; -export { PingListComponent } from './ping_list'; -export { PingHistogramComponent } from './charts'; -export { StatusPanel } from './status_panel'; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_bar/index.ts b/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_bar/index.ts deleted file mode 100644 index 0cb11587eee480..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_bar/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { MonitorSSLCertificate } from './monitor_ssl_certificate'; -export { MonitorStatusBarComponent } from './monitor_status_bar'; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/search_schema.ts b/x-pack/legacy/plugins/uptime/public/components/functional/search_schema.ts deleted file mode 100644 index bd451a98352881..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/components/functional/search_schema.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export const filterBarSearchSchema = { - strict: true, - fields: { - 'monitor.id': { type: 'string' }, - 'monitor.status': { type: 'string' }, - 'monitor.ip': { type: 'string' }, - 'monitor.host': { type: 'string' }, - 'monitor.scheme': { type: 'string' }, - 'url.port': { type: 'number' }, - }, -}; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/monitor_charts.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/monitor/__tests__/__snapshots__/monitor_charts.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/monitor_charts.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/monitor/__tests__/__snapshots__/monitor_charts.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/monitor_charts.test.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/__tests__/monitor_charts.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/__tests__/monitor_charts.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/__tests__/monitor_charts.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/index.ts b/x-pack/legacy/plugins/uptime/public/components/monitor/index.ts new file mode 100644 index 00000000000000..cb7b27afded023 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/index.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from './ml'; +export * from './ping_list'; +export * from './location_map'; +export * from './monitor_status_details'; +export * from './ping_histogram'; +export * from './monitor_charts'; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/__tests__/__snapshots__/location_map.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_map.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/location_map/__tests__/__snapshots__/location_map.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_map.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/__tests__/__snapshots__/location_missing.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_missing.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/location_map/__tests__/__snapshots__/location_missing.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_missing.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/__tests__/__snapshots__/location_status_tags.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_status_tags.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/location_map/__tests__/__snapshots__/location_status_tags.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_status_tags.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/__tests__/location_map.test.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/location_map.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/location_map/__tests__/location_map.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/location_map.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/__tests__/location_missing.test.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/location_missing.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/location_map/__tests__/location_missing.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/location_missing.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/__tests__/location_status_tags.test.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/location_status_tags.test.tsx similarity index 97% rename from x-pack/legacy/plugins/uptime/public/components/functional/location_map/__tests__/location_status_tags.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/location_status_tags.test.tsx index 2359938dbbc35a..7dde38af99fc33 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/__tests__/location_status_tags.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/location_status_tags.test.tsx @@ -8,9 +8,8 @@ import React from 'react'; import moment from 'moment'; import { renderWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers'; import { MonitorLocation } from '../../../../../common/runtime_types/monitor'; -import { LocationStatusTags } from '../'; +import { LocationStatusTags } from '../index'; -// Failing: https://github.com/elastic/kibana/issues/54818 describe('LocationStatusTags component', () => { let monitorLocations: MonitorLocation[]; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/__tests__/__mocks__/mock.ts b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/__tests__/__mocks__/mock.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/__tests__/__mocks__/mock.ts rename to x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/__tests__/__mocks__/mock.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/__tests__/map_config.test.ts b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/__tests__/map_config.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/__tests__/map_config.test.ts rename to x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/__tests__/map_config.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/embedded_map.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/embedded_map.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/embedded_map.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/embedded_map.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/low_poly_layer.json b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/low_poly_layer.json similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/low_poly_layer.json rename to x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/low_poly_layer.json diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/map_config.ts b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/map_config.ts similarity index 98% rename from x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/map_config.ts rename to x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/map_config.ts index a43edae4382527..ddb52e119fa879 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/map_config.ts +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/map_config.ts @@ -5,7 +5,7 @@ */ import lowPolyLayerFeatures from './low_poly_layer.json'; -import { LocationPoint } from './embedded_map.js'; +import { LocationPoint } from './embedded_map'; import { UptimeAppColors } from '../../../../uptime_app'; /** diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/translations.ts b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/translations.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/translations.ts rename to x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/translations.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/index.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/index.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/location_map/index.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/location_map/index.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/location_map.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/location_map.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/location_map/location_map.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/location_map/location_map.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/location_missing.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/location_missing.tsx similarity index 97% rename from x-pack/legacy/plugins/uptime/public/components/functional/location_map/location_missing.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/location_map/location_missing.tsx index a20889f6cc6537..6ce31e4cc8243f 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/location_missing.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/location_missing.tsx @@ -16,7 +16,7 @@ import { } from '@elastic/eui'; import styled from 'styled-components'; import { FormattedMessage } from '@kbn/i18n/react'; -import { LocationLink } from '../monitor_list/monitor_list_drawer'; +import { LocationLink } from '../../common/location_link'; const EuiPopoverRight = styled(EuiFlexItem)` margin-left: auto; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/location_status_tags.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/location_status_tags.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/location_map/location_status_tags.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/location_map/location_status_tags.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/__snapshots__/confirm_delete.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/confirm_delete.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/__snapshots__/confirm_delete.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/confirm_delete.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/__snapshots__/license_info.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/license_info.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/__snapshots__/license_info.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/license_info.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/__snapshots__/ml_flyout.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_flyout.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/__snapshots__/ml_flyout.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_flyout.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/__snapshots__/ml_integerations.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_integerations.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/__snapshots__/ml_integerations.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_integerations.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/__snapshots__/ml_job_link.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_job_link.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/__snapshots__/ml_job_link.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_job_link.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/__snapshots__/ml_manage_job.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_manage_job.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/__snapshots__/ml_manage_job.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_manage_job.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/confirm_delete.test.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/confirm_delete.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/confirm_delete.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/confirm_delete.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/license_info.test.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/license_info.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/license_info.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/license_info.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/ml_flyout.test.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/ml_flyout.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/ml_flyout.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/ml_flyout.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/ml_integerations.test.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/ml_integerations.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/ml_integerations.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/ml_integerations.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/ml_job_link.test.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/ml_job_link.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/ml_job_link.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/ml_job_link.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/ml_manage_job.test.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/ml_manage_job.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/__tests__/ml_manage_job.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/ml_manage_job.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/confirm_delete.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/confirm_delete.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/confirm_delete.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/confirm_delete.tsx diff --git a/x-pack/legacy/plugins/uptime/common/domain_types/index.ts b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/index.ts similarity index 81% rename from x-pack/legacy/plugins/uptime/common/domain_types/index.ts rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/index.ts index 1cf72ca2dac0b0..c644c94d138788 100644 --- a/x-pack/legacy/plugins/uptime/common/domain_types/index.ts +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export * from './monitors'; +export { ManageMLJobComponent } from './manage_ml_job'; diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/license_info.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/license_info.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/license_info.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/license_info.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/manage_ml_job.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/manage_ml_job.tsx similarity index 97% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/manage_ml_job.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/manage_ml_job.tsx index ec3e8bb2b9f68d..46ac24e9455e53 100644 --- a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/manage_ml_job.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/manage_ml_job.tsx @@ -13,7 +13,7 @@ import { UptimeSettingsContext } from '../../../contexts'; import * as labels from './translations'; import { getMLJobLinkHref } from './ml_job_link'; import { useGetUrlParams } from '../../../hooks'; -import { useMonitorId } from '../../../hooks/use_monitor'; +import { useMonitorId } from '../../../hooks'; interface Props { hasMLJob: boolean; diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/ml_flyout.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_flyout.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/ml_flyout.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_flyout.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/ml_flyout_container.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_flyout_container.tsx similarity index 98% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/ml_flyout_container.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_flyout_container.tsx index a13de192cc4437..c3e8579ca48370 100644 --- a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/ml_flyout_container.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_flyout_container.tsx @@ -25,7 +25,7 @@ import { ML_JOB_ID } from '../../../../common/constants'; import { UptimeRefreshContext, UptimeSettingsContext } from '../../../contexts'; import { useGetUrlParams } from '../../../hooks'; import { getDynamicSettings } from '../../../state/actions/dynamic_settings'; -import { useMonitorId } from '../../../hooks/use_monitor'; +import { useMonitorId } from '../../../hooks'; interface Props { onClose: () => void; diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/ml_integeration.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_integeration.tsx similarity index 98% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/ml_integeration.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_integeration.tsx index e053ca733cb8c3..4963a901f0ecc5 100644 --- a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/ml_integeration.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_integeration.tsx @@ -21,7 +21,7 @@ import * as labels from './translations'; import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public'; import { ManageMLJobComponent } from './manage_ml_job'; import { JobStat } from '../../../../../../../plugins/ml/common/types/data_recognizer'; -import { useMonitorId } from '../../../hooks/use_monitor'; +import { useMonitorId } from '../../../hooks'; export const MLIntegrationComponent = () => { const [isMlFlyoutOpen, setIsMlFlyoutOpen] = useState(false); diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/ml_job_link.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_job_link.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/ml_job_link.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_job_link.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/translations.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/translations.tsx similarity index 95% rename from x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/translations.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ml/translations.tsx index 32374674771e8e..bcc3fca770652b 100644 --- a/x-pack/legacy/plugins/uptime/public/components/monitor_details/ml/translations.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/ml/translations.tsx @@ -96,13 +96,6 @@ export const MANAGE_ANOMALY_DETECTION = i18n.translate( } ); -export const VIEW_EXISTING_JOB = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.callout.jobExistsDescription.viewJobLinkText', - { - defaultMessage: 'View existing job', - } -); - export const ML_MANAGEMENT_PAGE = i18n.translate( 'xpack.uptime.ml.enableAnomalyDetectionPanel.manageMLJobDescription.mlJobsPageLinkText', { diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_charts.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_charts.tsx similarity index 68% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_charts.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/monitor_charts.tsx index c5edd0fd859773..f9cc1aa52b9026 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_charts.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_charts.tsx @@ -6,7 +6,8 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { PingHistogram, DurationChart } from '../connected'; +import { PingHistogram } from './ping_histogram/ping_histogram_container'; +import { MonitorDuration } from './monitor_duration/monitor_duration_container'; interface MonitorChartsProps { monitorId: string; @@ -16,10 +17,10 @@ export const MonitorCharts = ({ monitorId }: MonitorChartsProps) => { return ( - + - + ); diff --git a/x-pack/legacy/plugins/maps/common/constants.ts b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_duration/index.ts similarity index 65% rename from x-pack/legacy/plugins/maps/common/constants.ts rename to x-pack/legacy/plugins/uptime/public/components/monitor/monitor_duration/index.ts index 98945653c25dc8..aa3230a3f9bc00 100644 --- a/x-pack/legacy/plugins/maps/common/constants.ts +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_duration/index.ts @@ -4,5 +4,5 @@ * you may not use this file except in compliance with the Elastic License. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -export * from '../../../../plugins/maps/common/constants'; +export { MonitorDuration } from './monitor_duration_container'; +export { MonitorDurationComponent } from './monitor_duration'; diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration.tsx new file mode 100644 index 00000000000000..af1c8dbdc49e38 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration.tsx @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle } from '@elastic/eui'; +import { LocationDurationLine } from '../../../../common/types'; +import { MLIntegrationComponent } from '../ml/ml_integeration'; +import { AnomalyRecords } from '../../../state/actions'; +import { DurationChartComponent } from '../../common/charts'; + +interface DurationChartProps { + loading: boolean; + hasMLJob: boolean; + anomalies: AnomalyRecords | null; + locationDurationLines: LocationDurationLine[]; +} + +/** + * This chart is intended to visualize monitor duration performance over time to + * the users in a helpful way. Its x-axis is based on a timeseries, the y-axis is in + * milliseconds. + * @param props The props required for this component to render properly + */ +export const MonitorDurationComponent = ({ + locationDurationLines, + anomalies, + loading, + hasMLJob, +}: DurationChartProps) => { + return ( + + + + +

+ {hasMLJob ? ( + + ) : ( + + )} +

+
+
+ + + +
+ +
+ ); +}; diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/charts/monitor_duration.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration_container.tsx similarity index 91% rename from x-pack/legacy/plugins/uptime/public/components/connected/charts/monitor_duration.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration_container.tsx index 40480905350aff..7e39b977f12710 100644 --- a/x-pack/legacy/plugins/uptime/public/components/connected/charts/monitor_duration.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration_container.tsx @@ -12,7 +12,6 @@ import { getMLCapabilitiesAction, getMonitorDurationAction, } from '../../../state/actions'; -import { DurationChartComponent } from '../../functional/charts'; import { anomaliesSelector, hasMLFeatureAvailable, @@ -22,12 +21,10 @@ import { import { UptimeRefreshContext } from '../../../contexts'; import { getMLJobId } from '../../../state/api/ml_anomaly'; import { JobStat } from '../../../../../../../plugins/ml/common/types/data_recognizer'; +import { MonitorDurationComponent } from './monitor_duration'; +import { MonitorIdParam } from '../../../../common/types'; -interface Props { - monitorId: string; -} - -export const DurationChart: React.FC = ({ monitorId }: Props) => { +export const MonitorDuration: React.FC = ({ monitorId }) => { const { dateRangeStart, dateRangeEnd, @@ -75,7 +72,7 @@ export const DurationChart: React.FC = ({ monitorId }: Props) => { }, [dispatch]); return ( - { let monitorLocations: MonitorLocation[]; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/index.ts b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/index.ts similarity index 64% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/index.ts rename to x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/index.ts index 385788cc825a0a..e95f14472e9e84 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/index.ts +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/index.ts @@ -5,5 +5,8 @@ */ export { MonitorStatusBarComponent } from './monitor_status_bar'; -export { MonitorStatusDetailsComponent } from './monitor_status_details'; +export { MonitorStatusDetailsComponent } from './status_details'; export { StatusByLocations } from './monitor_status_bar/status_by_location'; + +export { MonitorStatusDetails } from './status_details_container'; +export { MonitorStatusBar } from './monitor_status_bar/status_bar_container'; diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/index.ts b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/index.ts new file mode 100644 index 00000000000000..3c861412a39e91 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { MonitorSSLCertificate } from './ssl_certificate'; +export { MonitorStatusBarComponent } from './status_bar'; +export { MonitorStatusBar } from './status_bar_container'; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_bar/monitor_ssl_certificate.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/ssl_certificate.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_bar/monitor_ssl_certificate.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/ssl_certificate.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_bar/monitor_status_bar.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_bar.tsx similarity index 95% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_bar/monitor_status_bar.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_bar.tsx index ac3cedc5179956..36159dc29eccde 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_bar/monitor_status_bar.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_bar.tsx @@ -14,7 +14,7 @@ import { EuiFlexGroup, EuiFlexItem, } from '@elastic/eui'; -import { MonitorSSLCertificate } from './monitor_ssl_certificate'; +import { MonitorSSLCertificate } from './ssl_certificate'; import * as labels from './translations'; import { StatusByLocations } from './status_by_location'; import { Ping } from '../../../../../common/runtime_types'; @@ -22,7 +22,7 @@ import { MonitorLocations } from '../../../../../common/runtime_types'; interface MonitorStatusBarProps { monitorId: string; - monitorStatus: Ping; + monitorStatus: Ping | null; monitorLocations: MonitorLocations; } diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_bar_container.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_bar_container.tsx new file mode 100644 index 00000000000000..95622954375151 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_bar_container.tsx @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useContext, useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { monitorLocationsSelector, monitorStatusSelector } from '../../../../state/selectors'; +import { MonitorStatusBarComponent } from './index'; +import { getMonitorStatusAction } from '../../../../state/actions'; +import { useGetUrlParams } from '../../../../hooks'; +import { UptimeRefreshContext } from '../../../../contexts'; +import { MonitorIdParam } from '../../../../../common/types'; +import { AppState } from '../../../../state'; + +export const MonitorStatusBar: React.FC = ({ monitorId }) => { + const { lastRefresh } = useContext(UptimeRefreshContext); + + const { dateRangeStart: dateStart, dateRangeEnd: dateEnd } = useGetUrlParams(); + + const dispatch = useDispatch(); + + const monitorStatus = useSelector(monitorStatusSelector); + const monitorLocations = useSelector((state: AppState) => + monitorLocationsSelector(state, monitorId) + ); + + useEffect(() => { + dispatch(getMonitorStatusAction({ dateStart, dateEnd, monitorId })); + }, [monitorId, dateStart, dateEnd, lastRefresh, dispatch]); + + return ( + + ); +}; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_bar/status_by_location.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_by_location.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_bar/status_by_location.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_by_location.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_bar/translations.ts b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/translations.ts similarity index 99% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_bar/translations.ts rename to x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/translations.ts index 1c2844f4f6ccf2..f60a1ceeaafb84 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_bar/translations.ts +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/translations.ts @@ -3,6 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + import { i18n } from '@kbn/i18n'; export const healthStatusMessageAriaLabel = i18n.translate( diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_details.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/status_details.tsx similarity index 97% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_details.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/status_details.tsx index 7dea73da7bba0e..ebd16b05ecb4af 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_details.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/status_details.tsx @@ -10,7 +10,7 @@ import styled from 'styled-components'; import { LocationMap } from '../location_map'; import { UptimeRefreshContext } from '../../../contexts'; import { MonitorLocations } from '../../../../common/runtime_types'; -import { MonitorStatusBar } from '../../connected'; +import { MonitorStatusBar } from './monitor_status_bar'; interface MonitorStatusDetailsProps { monitorId: string; diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/status_details_container.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/status_details_container.tsx new file mode 100644 index 00000000000000..251f3562f9d1a3 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/status_details_container.tsx @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useContext, useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { useGetUrlParams } from '../../../hooks'; +import { monitorLocationsSelector } from '../../../state/selectors'; +import { getMonitorLocationsAction } from '../../../state/actions/monitor'; +import { MonitorStatusDetailsComponent } from './index'; +import { UptimeRefreshContext } from '../../../contexts'; +import { AppState } from '../../../state'; +import { MonitorIdParam } from '../../../../common/types'; + +export const MonitorStatusDetails: React.FC = ({ monitorId }) => { + const { lastRefresh } = useContext(UptimeRefreshContext); + + const { dateRangeStart: dateStart, dateRangeEnd: dateEnd } = useGetUrlParams(); + + const dispatch = useDispatch(); + const monitorLocations = useSelector((state: AppState) => + monitorLocationsSelector(state, monitorId) + ); + + useEffect(() => { + dispatch(getMonitorLocationsAction({ dateStart, dateEnd, monitorId })); + }, [monitorId, dateStart, dateEnd, lastRefresh, dispatch]); + + return ( + + ); +}; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/translations.ts b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/translations.ts similarity index 99% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/translations.ts rename to x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/translations.ts index 1c2844f4f6ccf2..f60a1ceeaafb84 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/translations.ts +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/translations.ts @@ -3,6 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + import { i18n } from '@kbn/i18n'; export const healthStatusMessageAriaLabel = i18n.translate( diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/pings/index.ts b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_histogram/index.ts similarity index 80% rename from x-pack/legacy/plugins/uptime/public/components/connected/pings/index.ts rename to x-pack/legacy/plugins/uptime/public/components/monitor/ping_histogram/index.ts index 95ced104e51882..c980b41167d0c0 100644 --- a/x-pack/legacy/plugins/uptime/public/components/connected/pings/index.ts +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_histogram/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { PingList, PingListProps } from './ping_list'; +export { PingHistogram } from './ping_histogram_container'; diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ping_histogram/ping_histogram_container.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_histogram/ping_histogram_container.tsx new file mode 100644 index 00000000000000..c0e17966f5b9f2 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_histogram/ping_histogram_container.tsx @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { PingHistogramComponent } from '../../common/charts'; +import { getPingHistogram } from '../../../state/actions'; +import { selectPingHistogram } from '../../../state/selectors'; +import { useGetUrlParams } from '../../../hooks'; +import { useMonitorId } from '../../../hooks'; +import { ResponsiveWrapperProps, withResponsiveWrapper } from '../../common/higher_order'; + +interface Props { + height: string; +} + +const Container: React.FC = ({ height }) => { + const { + statusFilter, + absoluteDateRangeStart, + absoluteDateRangeEnd, + dateRangeStart: dateStart, + dateRangeEnd: dateEnd, + } = useGetUrlParams(); + + const dispatch = useDispatch(); + const monitorId = useMonitorId(); + + const { loading, data, esKuery, lastRefresh } = useSelector(selectPingHistogram); + + useEffect(() => { + dispatch(getPingHistogram({ monitorId, dateStart, dateEnd, statusFilter, filters: esKuery })); + }, [dateStart, dateEnd, monitorId, statusFilter, lastRefresh, esKuery, dispatch]); + return ( + + ); +}; + +export const PingHistogram = withResponsiveWrapper(Container); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/__tests__/__snapshots__/doc_link_body.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/doc_link_body.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/ping_list/__tests__/__snapshots__/doc_link_body.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/doc_link_body.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/__tests__/__snapshots__/expanded_row.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/expanded_row.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/ping_list/__tests__/__snapshots__/expanded_row.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/expanded_row.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/__tests__/__snapshots__/ping_list.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/ping_list.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/ping_list/__tests__/__snapshots__/ping_list.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/ping_list.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/__tests__/doc_link_body.test.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/doc_link_body.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/ping_list/__tests__/doc_link_body.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/doc_link_body.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/__tests__/expanded_row.test.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/expanded_row.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/ping_list/__tests__/expanded_row.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/expanded_row.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/__tests__/ping_list.test.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/ping_list.test.tsx similarity index 99% rename from x-pack/legacy/plugins/uptime/public/components/functional/ping_list/__tests__/ping_list.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/ping_list.test.tsx index ec256a886aa16b..cb8413ba08a816 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/__tests__/ping_list.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/ping_list.test.tsx @@ -7,8 +7,8 @@ import React from 'react'; import { shallowWithIntl } from 'test_utils/enzyme_helpers'; import { PingListComponent, toggleDetails } from '../ping_list'; -import { ExpandedRowMap } from '../../monitor_list/types'; import { Ping, PingsResponse } from '../../../../../common/runtime_types'; +import { ExpandedRowMap } from '../../../overview/monitor_list/types'; describe('PingList component', () => { let response: PingsResponse; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/doc_link_body.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/doc_link_body.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/ping_list/doc_link_body.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/doc_link_body.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/expanded_row.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/expanded_row.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/ping_list/expanded_row.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/expanded_row.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/index.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/index.tsx similarity index 85% rename from x-pack/legacy/plugins/uptime/public/components/functional/ping_list/index.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/index.tsx index 808f3f90ef0150..7fc19bbc9622b2 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/index.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/index.tsx @@ -5,3 +5,4 @@ */ export { PingListComponent } from './ping_list'; +export { PingList } from './ping_list_container'; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/location_name.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/location_name.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/ping_list/location_name.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/location_name.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/ping_list.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/ping_list.tsx similarity index 98% rename from x-pack/legacy/plugins/uptime/public/components/functional/ping_list/ping_list.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/ping_list.tsx index 934dfd961f9e08..5dfc1c06474309 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/ping_list.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/ping_list.tsx @@ -26,9 +26,9 @@ import styled from 'styled-components'; import { Ping, GetPingsParams, DateRange } from '../../../../common/runtime_types'; import { convertMicrosecondsToMilliseconds as microsToMillis } from '../../../lib/helper'; import { LocationName } from './location_name'; -import { Pagination } from './../monitor_list'; +import { Pagination } from '../../overview/monitor_list'; import { PingListExpandedRowComponent } from './expanded_row'; -import { PingListProps } from '../../connected/pings'; +import { PingListProps } from './ping_list_container'; export const AllLocationOption = { 'data-test-subj': 'xpack.uptime.pingList.locationOptions.all', @@ -139,7 +139,7 @@ export const PingListComponent = (props: Props) => { })) ); - const hasStatus: boolean = pings.reduce( + const hasStatus = pings.reduce( (hasHttpStatus: boolean, currentPing) => hasHttpStatus || !!currentPing.http?.response?.status_code, false diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/pings/ping_list.tsx b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/ping_list_container.tsx similarity index 96% rename from x-pack/legacy/plugins/uptime/public/components/connected/pings/ping_list.tsx rename to x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/ping_list_container.tsx index 5b32a623495f16..3c3caab365e3a5 100644 --- a/x-pack/legacy/plugins/uptime/public/components/connected/pings/ping_list.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/ping_list_container.tsx @@ -10,7 +10,7 @@ import { selectPingList } from '../../../state/selectors'; import { getPings } from '../../../state/actions'; import { GetPingsParams } from '../../../../common/runtime_types'; import { UptimeSettingsContext } from '../../../contexts'; -import { PingListComponent } from '../../functional'; +import { PingListComponent } from './index'; export interface PingListProps { monitorId: string; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/overview_page_parsing_error_callout.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/overview/__tests__/__snapshots__/parsing_error_callout.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/overview_page_parsing_error_callout.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/overview/__tests__/__snapshots__/parsing_error_callout.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/snapshot.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/snapshot.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/snapshot_heading.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot_heading.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/snapshot_heading.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot_heading.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/overview_page_parsing_error_callout.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/__tests__/parsing_error_callout.test.tsx similarity index 76% rename from x-pack/legacy/plugins/uptime/public/components/functional/__tests__/overview_page_parsing_error_callout.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/__tests__/parsing_error_callout.test.tsx index fbe55dfedc2fc0..01204c33b79d56 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/overview_page_parsing_error_callout.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/__tests__/parsing_error_callout.test.tsx @@ -6,13 +6,13 @@ import React from 'react'; import { shallowWithIntl } from 'test_utils/enzyme_helpers'; -import { OverviewPageParsingErrorCallout } from '../overview_page_parsing_error_callout'; +import { ParsingErrorCallout } from '../parsing_error_callout'; describe('OverviewPageParsingErrorCallout', () => { it('renders without errors when a valid error is provided', () => { expect( shallowWithIntl( - ) @@ -21,6 +21,6 @@ describe('OverviewPageParsingErrorCallout', () => { it('renders without errors when an error with no message is provided', () => { const error: any = {}; - expect(shallowWithIntl()).toMatchSnapshot(); + expect(shallowWithIntl()).toMatchSnapshot(); }); }); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/snapshot.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/__tests__/snapshot.test.tsx similarity index 92% rename from x-pack/legacy/plugins/uptime/public/components/functional/__tests__/snapshot.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/__tests__/snapshot.test.tsx index 214b0394369f7a..cfcab673dcb35f 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/snapshot.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/__tests__/snapshot.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { shallowWithIntl } from 'test_utils/enzyme_helpers'; import { Snapshot } from '../../../../common/runtime_types'; -import { SnapshotComponent } from '../snapshot'; +import { SnapshotComponent } from '../snapshot/snapshot'; describe('Snapshot component', () => { const snapshot: Snapshot = { diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/snapshot_heading.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/__tests__/snapshot_heading.test.tsx similarity index 93% rename from x-pack/legacy/plugins/uptime/public/components/functional/__tests__/snapshot_heading.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/__tests__/snapshot_heading.test.tsx index 70d082b26d653d..805c116ef538a7 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/snapshot_heading.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/__tests__/snapshot_heading.test.tsx @@ -6,7 +6,7 @@ import { shallowWithIntl } from 'test_utils/enzyme_helpers'; import React from 'react'; -import { SnapshotHeading } from '../snapshot_heading'; +import { SnapshotHeading } from '../snapshot/snapshot_heading'; describe('SnapshotHeading', () => { it('renders custom heading for no down monitors', () => { diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/alerts/__tests__/alert_monitor_status.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/alerts/__tests__/alert_monitor_status.test.tsx similarity index 98% rename from x-pack/legacy/plugins/uptime/public/components/functional/alerts/__tests__/alert_monitor_status.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/alerts/__tests__/alert_monitor_status.test.tsx index af8d17d1fc2428..8f33b6f652b9d8 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/alerts/__tests__/alert_monitor_status.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/alerts/__tests__/alert_monitor_status.test.tsx @@ -14,8 +14,8 @@ import { mountWithIntl } from 'test_utils/enzyme_helpers'; describe('alert monitor status component', () => { describe('handleAlertFieldNumberChange', () => { - let mockSetIsInvalid: jest.Mock; - let mockSetFieldValue: jest.Mock; + let mockSetIsInvalid: jest.Mock; + let mockSetFieldValue: jest.Mock; beforeEach(() => { mockSetIsInvalid = jest.fn(); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/alerts/alert_monitor_status.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/alerts/alert_monitor_status.tsx similarity index 99% rename from x-pack/legacy/plugins/uptime/public/components/functional/alerts/alert_monitor_status.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/alerts/alert_monitor_status.tsx index b86e85f35b17d4..83892bf23dcedc 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/alerts/alert_monitor_status.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/alerts/alert_monitor_status.tsx @@ -19,7 +19,7 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { DataPublicPluginSetup } from 'src/plugins/data/public'; -import { KueryBar } from '../../connected/kuerybar/kuery_bar_container'; +import { KueryBar } from '..'; interface AlertFieldNumberProps { 'aria-label': string; diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/alerts/alert_monitor_status.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/alert_monitor_status.tsx similarity index 86% rename from x-pack/legacy/plugins/uptime/public/components/connected/alerts/alert_monitor_status.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/alert_monitor_status.tsx index 1529ab6db88753..9dd27db0be6072 100644 --- a/x-pack/legacy/plugins/uptime/public/components/connected/alerts/alert_monitor_status.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/alert_monitor_status.tsx @@ -7,8 +7,8 @@ import React from 'react'; import { useSelector } from 'react-redux'; import { DataPublicPluginSetup } from 'src/plugins/data/public'; -import { selectMonitorStatusAlert } from '../../../state/selectors'; -import { AlertMonitorStatusComponent } from '../../functional/alerts/alert_monitor_status'; +import { selectMonitorStatusAlert } from '../../../../state/selectors'; +import { AlertMonitorStatusComponent } from '../index'; interface Props { autocomplete: DataPublicPluginSetup['autocomplete']; diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/alerts/index.ts b/x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/connected/alerts/index.ts rename to x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/alerts/toggle_alert_flyout_button.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx similarity index 80% rename from x-pack/legacy/plugins/uptime/public/components/connected/alerts/toggle_alert_flyout_button.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx index 43b0be45365a13..45ba72d76fba65 100644 --- a/x-pack/legacy/plugins/uptime/public/components/connected/alerts/toggle_alert_flyout_button.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx @@ -6,8 +6,8 @@ import React from 'react'; import { useDispatch } from 'react-redux'; -import { ToggleAlertFlyoutButtonComponent } from '../../functional'; -import { setAlertFlyoutVisible } from '../../../state/actions'; +import { setAlertFlyoutVisible } from '../../../../state/actions'; +import { ToggleAlertFlyoutButtonComponent } from '../index'; export const ToggleAlertFlyoutButton = () => { const dispatch = useDispatch(); diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/alerts/uptime_alerts_flyout_wrapper.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/uptime_alerts_flyout_wrapper.tsx similarity index 83% rename from x-pack/legacy/plugins/uptime/public/components/connected/alerts/uptime_alerts_flyout_wrapper.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/uptime_alerts_flyout_wrapper.tsx index a49468ad3dd066..7bfd44a762455a 100644 --- a/x-pack/legacy/plugins/uptime/public/components/connected/alerts/uptime_alerts_flyout_wrapper.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/uptime_alerts_flyout_wrapper.tsx @@ -6,9 +6,9 @@ import React from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { UptimeAlertsFlyoutWrapperComponent } from '../../functional'; -import { setAlertFlyoutVisible } from '../../../state/actions'; -import { selectAlertFlyoutVisibility } from '../../../state/selectors'; +import { setAlertFlyoutVisible } from '../../../../state/actions'; +import { selectAlertFlyoutVisibility } from '../../../../state/selectors'; +import { UptimeAlertsFlyoutWrapperComponent } from '../index'; interface Props { alertTypeId?: string; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/alerts/index.ts b/x-pack/legacy/plugins/uptime/public/components/overview/alerts/index.ts similarity index 93% rename from x-pack/legacy/plugins/uptime/public/components/functional/alerts/index.ts rename to x-pack/legacy/plugins/uptime/public/components/overview/alerts/index.ts index 275333b60c5ee0..5ca0f4c3fe8a76 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/alerts/index.ts +++ b/x-pack/legacy/plugins/uptime/public/components/overview/alerts/index.ts @@ -8,3 +8,4 @@ export { AlertMonitorStatusComponent } from './alert_monitor_status'; export { ToggleAlertFlyoutButtonComponent } from './toggle_alert_flyout_button'; export { UptimeAlertsContextProvider } from './uptime_alerts_context_provider'; export { UptimeAlertsFlyoutWrapperComponent } from './uptime_alerts_flyout_wrapper'; +export * from './alerts_containers'; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/alerts/toggle_alert_flyout_button.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/alerts/toggle_alert_flyout_button.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/alerts/toggle_alert_flyout_button.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/alerts/toggle_alert_flyout_button.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/alerts/uptime_alerts_context_provider.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/alerts/uptime_alerts_context_provider.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/alerts/uptime_alerts_context_provider.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/alerts/uptime_alerts_context_provider.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/alerts/uptime_alerts_flyout_wrapper.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/alerts/uptime_alerts_flyout_wrapper.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/alerts/uptime_alerts_flyout_wrapper.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/alerts/uptime_alerts_flyout_wrapper.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/data_or_index_missing.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/data_or_index_missing.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/data_or_index_missing.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/data_or_index_missing.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/data_or_index_missing.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/data_or_index_missing.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/data_or_index_missing.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/data_or_index_missing.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/empty_state.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/empty_state.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/empty_state.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/empty_state.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/data_or_index_missing.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/data_or_index_missing.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/empty_state/data_or_index_missing.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/empty_state/data_or_index_missing.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/empty_state.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/empty_state/empty_state.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/empty_state/empty_state.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state_container.tsx similarity index 95% rename from x-pack/legacy/plugins/uptime/public/components/connected/empty_state/empty_state.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state_container.tsx index b0868af70480a5..9a62cb9cdaeeea 100644 --- a/x-pack/legacy/plugins/uptime/public/components/connected/empty_state/empty_state.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state_container.tsx @@ -8,7 +8,7 @@ import React, { useContext, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { indexStatusAction } from '../../../state/actions'; import { indexStatusSelector, selectDynamicSettings } from '../../../state/selectors'; -import { EmptyStateComponent } from '../../functional/empty_state/empty_state'; +import { EmptyStateComponent } from './index'; import { UptimeRefreshContext } from '../../../contexts'; import { getDynamicSettings } from '../../../state/actions/dynamic_settings'; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/empty_state_error.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state_error.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/empty_state/empty_state_error.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state_error.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/empty_state_loading.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state_loading.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/empty_state/empty_state_loading.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state_loading.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/index.ts b/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/index.ts new file mode 100644 index 00000000000000..9f2a668f4c3a55 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { EmptyStateComponent } from './empty_state'; +export { EmptyState } from './empty_state_container'; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/__snapshots__/filter_popover.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/filter_popover.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/__snapshots__/filter_popover.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/filter_popover.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/__snapshots__/filter_status_button.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/filter_status_button.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/__snapshots__/filter_status_button.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/filter_status_button.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/__snapshots__/parse_filter_map.test.ts.snap b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/parse_filter_map.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/__snapshots__/parse_filter_map.test.ts.snap rename to x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/parse_filter_map.test.ts.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/filter_popover.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/filter_popover.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/filter_popover.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/filter_popover.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/filter_status_button.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/filter_status_button.test.tsx similarity index 93% rename from x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/filter_status_button.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/filter_status_button.test.tsx index 1813229a97d1b5..2ad4d971cf3b04 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/filter_status_button.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/filter_status_button.test.tsx @@ -6,7 +6,7 @@ import React from 'react'; import { FilterStatusButton, FilterStatusButtonProps } from '../filter_status_button'; -import { shallowWithRouter } from '../../../../lib/'; +import { shallowWithRouter } from '../../../../lib'; describe('FilterStatusButton', () => { let props: FilterStatusButtonProps; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/parse_filter_map.test.ts b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/parse_filter_map.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/parse_filter_map.test.ts rename to x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/parse_filter_map.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/toggle_selected_item.test.ts b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/toggle_selected_item.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/toggle_selected_item.test.ts rename to x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/toggle_selected_item.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/filter_group.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/filter_group.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/filter_group/filter_group.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/filter_group/filter_group.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/filter_group/filter_group_container.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/filter_group_container.tsx similarity index 94% rename from x-pack/legacy/plugins/uptime/public/components/connected/filter_group/filter_group_container.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/filter_group/filter_group_container.tsx index 569c6bb883cbdc..3612604fdf1162 100644 --- a/x-pack/legacy/plugins/uptime/public/components/connected/filter_group/filter_group_container.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/filter_group_container.tsx @@ -7,10 +7,10 @@ import React, { useContext, useEffect } from 'react'; import { connect } from 'react-redux'; import { useUrlParams } from '../../../hooks'; -import { parseFiltersMap } from '../../functional/filter_group/parse_filter_map'; +import { parseFiltersMap } from './parse_filter_map'; import { AppState } from '../../../state'; import { fetchOverviewFilters, GetOverviewFiltersPayload } from '../../../state/actions'; -import { FilterGroupComponent } from '../../functional/filter_group'; +import { FilterGroupComponent } from './index'; import { OverviewFilters } from '../../../../common/runtime_types/overview_filters'; import { UptimeRefreshContext } from '../../../contexts'; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/filter_popover.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/filter_popover.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/filter_group/filter_popover.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/filter_group/filter_popover.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/filter_status_button.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/filter_status_button.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/filter_group/filter_status_button.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/filter_group/filter_status_button.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/index.ts b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/index.ts similarity index 84% rename from x-pack/legacy/plugins/uptime/public/components/functional/filter_group/index.ts rename to x-pack/legacy/plugins/uptime/public/components/overview/filter_group/index.ts index 2aae026144d8f8..933fddf1cde278 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/index.ts +++ b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/index.ts @@ -5,3 +5,4 @@ */ export { FilterGroupComponent } from './filter_group'; +export { FilterGroup } from './filter_group_container'; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/parse_filter_map.ts b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/parse_filter_map.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/filter_group/parse_filter_map.ts rename to x-pack/legacy/plugins/uptime/public/components/overview/filter_group/parse_filter_map.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/toggle_selected_item.ts b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/toggle_selected_item.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/filter_group/toggle_selected_item.ts rename to x-pack/legacy/plugins/uptime/public/components/overview/filter_group/toggle_selected_item.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/uptime_filter_button.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/uptime_filter_button.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/filter_group/uptime_filter_button.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/filter_group/uptime_filter_button.tsx diff --git a/x-pack/legacy/plugins/maps/public/legacy_register_feature.ts b/x-pack/legacy/plugins/uptime/public/components/overview/index.ts similarity index 50% rename from x-pack/legacy/plugins/maps/public/legacy_register_feature.ts rename to x-pack/legacy/plugins/uptime/public/components/overview/index.ts index 00f788f267d4b1..ac293e9233c8cf 100644 --- a/x-pack/legacy/plugins/maps/public/legacy_register_feature.ts +++ b/x-pack/legacy/plugins/uptime/public/components/overview/index.ts @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { npSetup } from 'ui/new_platform'; -import { featureCatalogueEntry } from './feature_catalogue_entry'; +export * from './monitor_list'; +export * from './empty_state'; +export * from './filter_group'; +export * from './alerts'; +export * from './snapshot'; +export * from './kuery_bar'; -const { - plugins: { home }, -} = npSetup; - -home.featureCatalogue.register(featureCatalogueEntry); +export { ParsingErrorCallout } from './parsing_error_callout'; diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/index.ts b/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/index.ts new file mode 100644 index 00000000000000..60801a0ab705a1 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { KueryBarComponent } from './kuery_bar'; +export { KueryBar } from './kuery_bar_container'; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/kuery_bar.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/kuery_bar.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/kuery_bar.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/kuery_bar.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/kuerybar/kuery_bar_container.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/kuery_bar_container.tsx similarity index 90% rename from x-pack/legacy/plugins/uptime/public/components/connected/kuerybar/kuery_bar_container.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/kuery_bar_container.tsx index 132ae57b5154f6..5e1e184b2d6e6f 100644 --- a/x-pack/legacy/plugins/uptime/public/components/connected/kuerybar/kuery_bar_container.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/kuery_bar_container.tsx @@ -8,7 +8,7 @@ import { connect } from 'react-redux'; import { AppState } from '../../../state'; import { selectIndexPattern } from '../../../state/selectors'; import { getIndexPattern } from '../../../state/actions'; -import { KueryBarComponent } from '../../functional/kuery_bar/kuery_bar'; +import { KueryBarComponent } from './kuery_bar'; const mapStateToProps = (state: AppState) => ({ ...selectIndexPattern(state) }); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/typeahead/click_outside.js b/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/click_outside.js similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/typeahead/click_outside.js rename to x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/click_outside.js diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/typeahead/index.d.ts b/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/index.d.ts similarity index 95% rename from x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/typeahead/index.d.ts rename to x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/index.d.ts index c9f43b3a620bdd..defde6203a8c53 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/typeahead/index.d.ts +++ b/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/index.d.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Component } from 'react'; +import React from 'react'; interface TypeaheadProps { onChange: (inputValue: string, selectionStart: number) => void; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/typeahead/index.js b/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/index.js similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/typeahead/index.js rename to x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/index.js diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/typeahead/suggestion.js b/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestion.js similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/typeahead/suggestion.js rename to x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestion.js diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/typeahead/suggestions.js b/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestions.js similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/kuery_bar/typeahead/suggestions.js rename to x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestions.js diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/__tests__/__snapshots__/monitor_list_status_column.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list_status_column.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/__tests__/__snapshots__/monitor_list_status_column.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list_status_column.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/__tests__/__snapshots__/monitor_page_link.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_page_link.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/__tests__/__snapshots__/monitor_page_link.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_page_link.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/__tests__/monitor_list.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/__tests__/monitor_list.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/__tests__/monitor_list_page_size_select.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list_page_size_select.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/__tests__/monitor_list_page_size_select.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list_page_size_select.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/__tests__/monitor_list_status_column.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list_status_column.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/__tests__/monitor_list_status_column.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list_status_column.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/__tests__/monitor_page_link.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_page_link.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/__tests__/monitor_page_link.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_page_link.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/__tests__/parse_timestamp.test.ts b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/parse_timestamp.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/__tests__/parse_timestamp.test.ts rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/parse_timestamp.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/index.ts b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/index.ts similarity index 69% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/index.ts rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/index.ts index 2dc43050f95155..45e8822a317a4f 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/index.ts +++ b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/index.ts @@ -7,3 +7,5 @@ export { MonitorListComponent } from './monitor_list'; export { Criteria, Pagination } from './types'; export { LocationLink } from './monitor_list_drawer'; +export { MonitorListDrawer } from './monitor_list_drawer/list_drawer_container'; +export { ActionsPopover } from './monitor_list_drawer/actions_popover/actions_popover_container'; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx similarity index 97% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx index 6705101ccd5723..18e2e2437e1477 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx @@ -22,13 +22,13 @@ import { HistogramPoint, FetchMonitorStatesQueryArgs } from '../../../../common/ import { MonitorSummary } from '../../../../common/runtime_types'; import { MonitorListStatusColumn } from './monitor_list_status_column'; import { ExpandedRowMap } from './types'; -import { MonitorBarSeries } from '../charts'; +import { MonitorBarSeries } from '../../common/charts'; import { MonitorPageLink } from './monitor_page_link'; import { OverviewPageLink } from './overview_page_link'; import * as labels from './translations'; -import { MonitorListDrawer } from '../../connected'; import { MonitorListPageSizeSelect } from './monitor_list_page_size_select'; -import { MonitorListProps } from '../../connected/monitor/monitor_list'; +import { MonitorListDrawer } from './monitor_list_drawer/list_drawer_container'; +import { MonitorListProps } from './monitor_list_container'; import { MonitorList } from '../../../state/reducers/monitor_list'; import { useUrlParams } from '../../../hooks'; diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/monitor/monitor_list.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_container.tsx similarity index 93% rename from x-pack/legacy/plugins/uptime/public/components/connected/monitor/monitor_list.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_container.tsx index c9457664566b75..5bfe6ff0c5b4f1 100644 --- a/x-pack/legacy/plugins/uptime/public/components/connected/monitor/monitor_list.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_container.tsx @@ -9,7 +9,7 @@ import { useSelector, useDispatch } from 'react-redux'; import { getMonitorList } from '../../../state/actions'; import { FetchMonitorStatesQueryArgs } from '../../../../common/runtime_types'; import { monitorListSelector } from '../../../state/selectors'; -import { MonitorListComponent } from '../../functional/monitor_list'; +import { MonitorListComponent } from './index'; export interface MonitorListProps { filters?: string; @@ -18,13 +18,16 @@ export interface MonitorListProps { export const MonitorList: React.FC = props => { const dispatch = useDispatch(); + const dispatchCallback = useCallback( (params: FetchMonitorStatesQueryArgs) => { dispatch(getMonitorList(params)); }, [dispatch] ); + const monitorListState = useSelector(monitorListSelector); + return ( ); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_group.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_group.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_group.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_group.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_link.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_link.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_link.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_link.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_list_drawer.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_list_drawer.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_list_drawer.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_list_drawer.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_list.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_list.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_list.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_list.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_row.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_row.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_row.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_row.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/most_recent_error.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/most_recent_error.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/most_recent_error.test.tsx.snap rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/most_recent_error.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/data.json b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/data.json similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/data.json rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/data.json diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/integration_group.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_group.test.tsx similarity index 94% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/integration_group.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_group.test.tsx index 48fa2c97666819..25cf400bcd0fdb 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/integration_group.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_group.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { MonitorSummary } from '../../../../../../common/runtime_types'; import { shallowWithIntl } from 'test_utils/enzyme_helpers'; -import { IntegrationGroup } from '../integration_group'; +import { IntegrationGroup } from '../actions_popover/integration_group'; describe('IntegrationGroup', () => { let summary: MonitorSummary; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/integration_link.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_link.test.tsx similarity index 93% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/integration_link.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_link.test.tsx index ba313f255f13d1..8ee83bc38957b1 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/integration_link.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_link.test.tsx @@ -5,7 +5,7 @@ */ import React from 'react'; -import { IntegrationLink } from '../integration_link'; +import { IntegrationLink } from '../actions_popover/integration_link'; import { shallowWithIntl } from 'test_utils/enzyme_helpers'; describe('IntegrationLink component', () => { diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/monitor_list_drawer.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_list_drawer.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/monitor_list_drawer.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_list_drawer.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/monitor_status_list.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_status_list.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/monitor_status_list.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_status_list.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/monitor_status_row.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_status_row.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/monitor_status_row.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_status_row.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/most_recent_error.test.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/most_recent_error.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/most_recent_error.test.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/most_recent_error.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/monitor_list_actions_popover.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/actions_popover.tsx similarity index 89% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/monitor_list_actions_popover.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/actions_popover.tsx index c57ecbaa4d3ed5..e86e6b309214fe 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/monitor_list_actions_popover.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/actions_popover.tsx @@ -9,20 +9,20 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import { EuiPopover, EuiButton } from '@elastic/eui'; import { IntegrationGroup } from './integration_group'; -import { MonitorSummary } from '../../../../../common/runtime_types'; -import { toggleIntegrationsPopover, PopoverState } from '../../../../state/actions'; +import { MonitorSummary } from '../../../../../../common/runtime_types'; +import { toggleIntegrationsPopover, PopoverState } from '../../../../../state/actions'; -interface MonitorListActionsPopoverProps { +interface ActionsPopoverProps { summary: MonitorSummary; popoverState: PopoverState | null; togglePopoverIsVisible: typeof toggleIntegrationsPopover; } -export const MonitorListActionsPopoverComponent = ({ +export const ActionsPopoverComponent = ({ summary, popoverState, togglePopoverIsVisible, -}: MonitorListActionsPopoverProps) => { +}: ActionsPopoverProps) => { const popoverId = `${summary.monitor_id}_popover`; const monitorUrl: string | undefined = get(summary, 'state.url.full', undefined); diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/monitor/drawer_popover_container.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/actions_popover_container.tsx similarity index 63% rename from x-pack/legacy/plugins/uptime/public/components/connected/monitor/drawer_popover_container.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/actions_popover_container.tsx index be29e12f716a94..b1c25ddd7a3382 100644 --- a/x-pack/legacy/plugins/uptime/public/components/connected/monitor/drawer_popover_container.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/actions_popover_container.tsx @@ -5,10 +5,10 @@ */ import { connect } from 'react-redux'; -import { AppState } from '../../../state'; -import { isIntegrationsPopupOpen } from '../../../state/selectors'; -import { PopoverState, toggleIntegrationsPopover } from '../../../state/actions'; -import { MonitorListActionsPopoverComponent } from '../../functional/monitor_list/monitor_list_drawer'; +import { AppState } from '../../../../../state'; +import { isIntegrationsPopupOpen } from '../../../../../state/selectors'; +import { PopoverState, toggleIntegrationsPopover } from '../../../../../state/actions'; +import { ActionsPopoverComponent } from '../index'; const mapStateToProps = (state: AppState) => ({ popoverState: isIntegrationsPopupOpen(state), @@ -20,7 +20,4 @@ const mapDispatchToProps = (dispatch: any) => ({ }, }); -export const MonitorListActionsPopover = connect( - mapStateToProps, - mapDispatchToProps -)(MonitorListActionsPopoverComponent); +export const ActionsPopover = connect(mapStateToProps, mapDispatchToProps)(ActionsPopoverComponent); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/integration_group.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_group.tsx similarity index 98% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/integration_group.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_group.tsx index cc06b9a2306c70..bbcba7238748d1 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/integration_group.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_group.tsx @@ -18,9 +18,9 @@ import { getLoggingContainerHref, getLoggingIpHref, getLoggingKubernetesHref, -} from '../../../../lib/helper'; -import { MonitorSummary } from '../../../../../common/runtime_types'; -import { UptimeSettingsContext } from '../../../../contexts'; +} from '../../../../../lib/helper'; +import { MonitorSummary } from '../../../../../../common/runtime_types'; +import { UptimeSettingsContext } from '../../../../../contexts'; interface IntegrationGroupProps { summary: MonitorSummary; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/integration_link.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_link.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/integration_link.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_link.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/index.ts b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/index.ts similarity index 63% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/index.ts rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/index.ts index 2933a71c2240b3..32c722b806f2ba 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/index.ts +++ b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/index.ts @@ -4,5 +4,5 @@ * you may not use this file except in compliance with the Elastic License. */ -export { LocationLink } from './location_link'; -export { MonitorListActionsPopoverComponent } from './monitor_list_actions_popover'; +export { LocationLink } from '../../../common/location_link'; +export { ActionsPopoverComponent } from './actions_popover/actions_popover'; diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/monitor/list_drawer_container.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/list_drawer_container.tsx similarity index 72% rename from x-pack/legacy/plugins/uptime/public/components/connected/monitor/list_drawer_container.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/list_drawer_container.tsx index 37a96ba0396aa5..bec32ace27f2b2 100644 --- a/x-pack/legacy/plugins/uptime/public/components/connected/monitor/list_drawer_container.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/list_drawer_container.tsx @@ -6,13 +6,13 @@ import React, { useEffect } from 'react'; import { connect } from 'react-redux'; -import { AppState } from '../../../state'; -import { monitorDetailsSelector } from '../../../state/selectors'; -import { MonitorDetailsActionPayload } from '../../../state/actions/types'; -import { getMonitorDetailsAction } from '../../../state/actions/monitor'; -import { MonitorListDrawerComponent } from '../../functional/monitor_list/monitor_list_drawer/monitor_list_drawer'; -import { useGetUrlParams } from '../../../hooks'; -import { MonitorDetails, MonitorSummary } from '../../../../common/runtime_types'; +import { AppState } from '../../../../state'; +import { monitorDetailsSelector } from '../../../../state/selectors'; +import { MonitorDetailsActionPayload } from '../../../../state/actions/types'; +import { getMonitorDetailsAction } from '../../../../state/actions/monitor'; +import { MonitorListDrawerComponent } from './monitor_list_drawer'; +import { useGetUrlParams } from '../../../../hooks'; +import { MonitorDetails, MonitorSummary } from '../../../../../common/runtime_types'; interface ContainerProps { summary: MonitorSummary; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/monitor_list_drawer.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_list_drawer.tsx similarity index 93% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/monitor_list_drawer.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_list_drawer.tsx index 6dc9ebbef1287d..8e97ce4d692d70 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/monitor_list_drawer.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_list_drawer.tsx @@ -10,7 +10,7 @@ import { EuiLink, EuiSpacer, EuiFlexGroup, EuiFlexItem, EuiIcon, EuiText } from import { MostRecentError } from './most_recent_error'; import { MonitorStatusList } from './monitor_status_list'; import { MonitorDetails, MonitorSummary } from '../../../../../common/runtime_types'; -import { MonitorListActionsPopover } from '../../../connected'; +import { ActionsPopover } from './actions_popover/actions_popover_container'; const ContainerDiv = styled.div` padding: 10px; @@ -48,7 +48,7 @@ export function MonitorListDrawerComponent({ summary, monitorDetails }: MonitorL - + diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/monitor_status_list.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_list.tsx similarity index 97% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/monitor_status_list.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_list.tsx index 8a46167dcd3bc0..cd1a5a95b8adb5 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/monitor_status_list.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_list.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { get, capitalize } from 'lodash'; import { EuiCallOut, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { LocationLink } from './location_link'; +import { LocationLink } from '../../../common/location_link'; import { MonitorStatusRow } from './monitor_status_row'; import { Check } from '../../../../../common/runtime_types'; import { STATUS, UNNAMED_LOCATION } from '../../../../../common/constants'; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/monitor_status_row.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_row.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/monitor_status_row.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_row.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/most_recent_error.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/most_recent_error.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/most_recent_error.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/most_recent_error.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_page_size_select.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_page_size_select.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_page_size_select.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_page_size_select.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_status_column.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_status_column.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_status_column.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_status_column.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_page_link.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_page_link.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_page_link.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_page_link.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/overview_page_link.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/overview_page_link.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/overview_page_link.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/overview_page_link.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/parse_timestamp.ts b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/parse_timestamp.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/parse_timestamp.ts rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/parse_timestamp.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/translations.ts b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/translations.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/translations.ts rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/translations.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/types.ts b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/types.ts similarity index 83% rename from x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/types.ts rename to x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/types.ts index a25603d3603d9f..6a6cee4a7d96da 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/types.ts +++ b/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/types.ts @@ -4,13 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -export interface CondensedCheck { - childStatuses: CondensedCheckStatus[]; - location: string | null; - status: string; - timestamp: string; -} - export interface CondensedCheckStatus { ip?: string | null; status: string; diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/pages/overview_container.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/overview_container.tsx similarity index 74% rename from x-pack/legacy/plugins/uptime/public/components/connected/pages/overview_container.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/overview_container.tsx index 79aaa071507e18..d64e489c480768 100644 --- a/x-pack/legacy/plugins/uptime/public/components/connected/pages/overview_container.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/overview_container.tsx @@ -5,10 +5,10 @@ */ import { connect } from 'react-redux'; -import { OverviewPageComponent } from '../../../pages/overview'; -import { selectIndexPattern } from '../../../state/selectors'; -import { AppState } from '../../../state'; -import { setEsKueryString } from '../../../state/actions'; +import { OverviewPageComponent } from '../../pages/overview'; +import { selectIndexPattern } from '../../state/selectors'; +import { AppState } from '../../state'; +import { setEsKueryString } from '../../state/actions'; interface DispatchProps { setEsKueryFilters: typeof setEsKueryString; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/overview_page_parsing_error_callout.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/parsing_error_callout.tsx similarity index 89% rename from x-pack/legacy/plugins/uptime/public/components/functional/overview_page_parsing_error_callout.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/parsing_error_callout.tsx index b71a4f2f8646a5..96ea14cdf9f37a 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/overview_page_parsing_error_callout.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/parsing_error_callout.tsx @@ -13,13 +13,11 @@ interface HasMessage { message: string; } -interface OverviewPageParsingErrorCalloutProps { +interface ParsingErrorCalloutProps { error: HasMessage; } -export const OverviewPageParsingErrorCallout = ({ - error, -}: OverviewPageParsingErrorCalloutProps) => ( +export const ParsingErrorCallout = ({ error }: ParsingErrorCalloutProps) => ( = ({ height }: Props) => { + const { dateRangeStart, dateRangeEnd, statusFilter } = useGetUrlParams(); + + const { count, lastRefresh, loading, esKuery } = useSelector(snapshotDataSelector); + + const dispatch = useDispatch(); + + useEffect(() => { + dispatch( + getSnapshotCountAction({ dateRangeStart, dateRangeEnd, filters: esKuery, statusFilter }) + ); + }, [dateRangeStart, dateRangeEnd, esKuery, lastRefresh, statusFilter, dispatch]); + return ; +}; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/snapshot_heading.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/snapshot/snapshot_heading.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/functional/snapshot_heading.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/snapshot/snapshot_heading.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/status_panel.tsx b/x-pack/legacy/plugins/uptime/public/components/overview/status_panel.tsx similarity index 87% rename from x-pack/legacy/plugins/uptime/public/components/functional/status_panel.tsx rename to x-pack/legacy/plugins/uptime/public/components/overview/status_panel.tsx index 2c0be2aa15d6fb..9edcb08a6d5b12 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/status_panel.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/overview/status_panel.tsx @@ -6,7 +6,8 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; -import { PingHistogram, Snapshot } from '../connected'; +import { PingHistogram } from '../monitor'; +import { Snapshot } from './snapshot/snapshot_container'; const STATUS_CHART_HEIGHT = '160px'; diff --git a/x-pack/legacy/plugins/uptime/public/contexts/uptime_settings_context.tsx b/x-pack/legacy/plugins/uptime/public/contexts/uptime_settings_context.tsx index c5a0ec48317988..137846de103b4d 100644 --- a/x-pack/legacy/plugins/uptime/public/contexts/uptime_settings_context.tsx +++ b/x-pack/legacy/plugins/uptime/public/contexts/uptime_settings_context.tsx @@ -7,7 +7,7 @@ import React, { createContext, useMemo } from 'react'; import { UptimeAppProps } from '../uptime_app'; import { CLIENT_DEFAULTS, CONTEXT_DEFAULTS } from '../../common/constants'; -import { CommonlyUsedRange } from '../components/functional/uptime_date_picker'; +import { CommonlyUsedRange } from '../components/common/uptime_date_picker'; import { useGetUrlParams } from '../hooks'; import { ILicense } from '../../../../../plugins/licensing/common/types'; diff --git a/x-pack/legacy/plugins/uptime/public/hooks/__tests__/use_breadcrumbs.test.tsx b/x-pack/legacy/plugins/uptime/public/hooks/__tests__/use_breadcrumbs.test.tsx index 85961003fce720..1ce00fe7ce3af5 100644 --- a/x-pack/legacy/plugins/uptime/public/hooks/__tests__/use_breadcrumbs.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/hooks/__tests__/use_breadcrumbs.test.tsx @@ -11,7 +11,7 @@ import { mountWithRouter } from '../../lib'; import { OVERVIEW_ROUTE } from '../../../common/constants'; import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public'; import { UptimeUrlParams, getSupportedUrlParams } from '../../lib/helper'; -import { makeBaseBreadcrumb, useBreadcrumbs } from '../../hooks/use_breadcrumbs'; +import { makeBaseBreadcrumb, useBreadcrumbs } from '../use_breadcrumbs'; describe('useBreadcrumbs', () => { it('sets the given breadcrumbs', () => { diff --git a/x-pack/legacy/plugins/uptime/public/lib/alert_types/index.ts b/x-pack/legacy/plugins/uptime/public/lib/alert_types/index.ts index f764505a6d683e..74160577cb0b13 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/alert_types/index.ts +++ b/x-pack/legacy/plugins/uptime/public/lib/alert_types/index.ts @@ -6,7 +6,7 @@ // TODO: after NP migration is complete we should be able to remove this lint ignore comment // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { AlertTypeModel } from '../../../../../../plugins/triggers_actions_ui/public/types'; +import { AlertTypeModel } from '../../../../../../plugins/triggers_actions_ui/public'; import { initMonitorStatusAlertType } from './monitor_status'; export type AlertTypeInitializer = (dependenies: { autocomplete: any }) => AlertTypeModel; diff --git a/x-pack/legacy/plugins/uptime/public/lib/alert_types/monitor_status.tsx b/x-pack/legacy/plugins/uptime/public/lib/alert_types/monitor_status.tsx index d059274159c7f4..0624d20b197c0e 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/alert_types/monitor_status.tsx +++ b/x-pack/legacy/plugins/uptime/public/lib/alert_types/monitor_status.tsx @@ -16,7 +16,7 @@ import { } from '../../../../../../plugins/triggers_actions_ui/public/types'; import { AlertTypeInitializer } from '.'; import { StatusCheckExecutorParamsType } from '../../../common/runtime_types'; -import { AlertMonitorStatus } from '../../components/connected/alerts'; +import { AlertMonitorStatus } from '../../components/overview/alerts/alerts_containers'; export const validate = (alertParams: any): ValidationResult => { const errors: Record = {}; diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_chart_date_label.ts b/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_chart_date_label.ts index 126b1d85f749f0..aa5a2b0f60e4f4 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_chart_date_label.ts +++ b/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_chart_date_label.ts @@ -11,7 +11,7 @@ import { CHART_FORMAT_LIMITS } from '../../../../common/constants'; /** * Generates an appropriate date formatting string intended for the y-axis * label of timeseries charts. The function will return day/month values for shorter - * timespans that cross the local date threshold, otherwise it estimates an appropriate + * time spans that cross the local date threshold, otherwise it estimates an appropriate * label for several different stops. * @param dateRangeStart the beginning of the date range * @param dateRangeEnd the end of the date range diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_label_format.ts b/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_label_format.ts index 668147fee80551..5957123e9257dc 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_label_format.ts +++ b/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_label_format.ts @@ -49,7 +49,7 @@ const dateStops: Array<{ key: number; value: string }> = [ ]; /** - * Returns an appropriate label format bbased on pre-defined intervals. + * Returns an appropriate label format based on pre-defined intervals. * @param delta The length of the timespan in milliseconds */ export const getLabelFormat = (delta: number): string => { diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/convert_measurements.ts b/x-pack/legacy/plugins/uptime/public/lib/helper/convert_measurements.ts index 4ad9b81b9e660c..da97b6400a9a53 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/helper/convert_measurements.ts +++ b/x-pack/legacy/plugins/uptime/public/lib/helper/convert_measurements.ts @@ -8,7 +8,7 @@ const NUM_MICROSECONDS_IN_MILLISECOND = 1000; /** * This simply converts microseconds to milliseconds. People tend to prefer ms to us - * when visualizaing request duration times. + * when visualizing request duration times. */ export const convertMicrosecondsToMilliseconds = (microseconds: number | null): number | null => { if (!microseconds && microseconds !== 0) return null; diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/__tests__/parse_absolute_date.test.ts b/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/__tests__/parse_absolute_date.test.ts index 691b38bdf9ca20..16888aec21cfe1 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/__tests__/parse_absolute_date.test.ts +++ b/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/__tests__/parse_absolute_date.test.ts @@ -24,7 +24,7 @@ describe('parseAbsoluteDate', () => { it('returns the default value if the parser provides `undefined`', () => { dateMathSpy.mockReturnValue(undefined); - const result = parseAbsoluteDate('this is not a valid datae', 12345); + const result = parseAbsoluteDate('this is not a valid date', 12345); expect(result).toBe(12345); }); }); diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/__tests__/parse_autorefresh_interval.test.ts b/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/__tests__/parse_autorefresh_interval.test.ts deleted file mode 100644 index a5c2168378089d..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/__tests__/parse_autorefresh_interval.test.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { parseUrlInt } from '../parse_url_int'; - -describe('parseUrlInt', () => { - it('parses a number', () => { - const result = parseUrlInt('23', 50); - expect(result).toBe(23); - }); - - it('returns default value for empty string', () => { - const result = parseUrlInt('', 50); - expect(result).toBe(50); - }); - - it('returns default value for non-numeric string', () => { - const result = parseUrlInt('abc', 50); - expect(result).toBe(50); - }); -}); diff --git a/x-pack/legacy/plugins/uptime/public/lib/lib.ts b/x-pack/legacy/plugins/uptime/public/lib/lib.ts index 6b6191441c9316..7dd3aa9eed5ce0 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/lib.ts +++ b/x-pack/legacy/plugins/uptime/public/lib/lib.ts @@ -5,7 +5,6 @@ */ import { ReactElement } from 'react'; -import { ChromeBreadcrumb } from 'src/core/public'; import { UMBadge } from '../badge'; import { UptimeAppProps } from '../uptime_app'; @@ -13,8 +12,6 @@ export interface UMFrontendLibs { framework: UMFrameworkAdapter; } -export type UMUpdateBreadcrumbs = (breadcrumbs: ChromeBreadcrumb[]) => void; - export type UMUpdateBadge = (badge: UMBadge) => void; export type BootstrapUptimeApp = (props: UptimeAppProps) => ReactElement; diff --git a/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx b/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx index 683af81239c992..4495be9b24dc1f 100644 --- a/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx +++ b/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx @@ -8,12 +8,13 @@ import { EuiSpacer } from '@elastic/eui'; import React from 'react'; import { useSelector } from 'react-redux'; import { useTrackPageview } from '../../../../../plugins/observability/public'; -import { MonitorStatusDetails, PingList } from '../components/connected'; import { monitorStatusSelector } from '../state/selectors'; import { PageHeader } from './page_header'; -import { MonitorCharts } from '../components/functional'; import { useBreadcrumbs } from '../hooks/use_breadcrumbs'; import { useMonitorId, useUptimeTelemetry, UptimePage } from '../hooks'; +import { MonitorCharts } from '../components/monitor'; +import { MonitorStatusDetails } from '../components/monitor'; +import { PingList } from '../components/monitor'; export const MonitorPage: React.FC = () => { const monitorId = useMonitorId(); diff --git a/x-pack/legacy/plugins/uptime/public/pages/overview.tsx b/x-pack/legacy/plugins/uptime/public/pages/overview.tsx index 5b51a208a4c37b..adc36efa6f7db1 100644 --- a/x-pack/legacy/plugins/uptime/public/pages/overview.tsx +++ b/x-pack/legacy/plugins/uptime/public/pages/overview.tsx @@ -8,15 +8,16 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import React, { useEffect } from 'react'; import styled from 'styled-components'; import { i18n } from '@kbn/i18n'; -import { OverviewPageParsingErrorCallout, StatusPanel } from '../components/functional'; import { useUptimeTelemetry, UptimePage, useGetUrlParams } from '../hooks'; import { stringifyUrlParams } from '../lib/helper/stringify_url_params'; import { useTrackPageview } from '../../../../../plugins/observability/public'; import { DataPublicPluginSetup, IIndexPattern } from '../../../../../../src/plugins/data/public'; -import { EmptyState, FilterGroup, KueryBar, MonitorList } from '../components/connected'; import { useUpdateKueryString } from '../hooks'; import { PageHeader } from './page_header'; import { useBreadcrumbs } from '../hooks/use_breadcrumbs'; +import { MonitorList } from '../components/overview/monitor_list/monitor_list_container'; +import { EmptyState, FilterGroup, KueryBar, ParsingErrorCallout } from '../components/overview'; +import { StatusPanel } from '../components/overview/status_panel'; interface OverviewPageProps { autocomplete: DataPublicPluginSetup['autocomplete']; @@ -75,7 +76,7 @@ export const OverviewPageComponent = ({ autocomplete, indexPattern, setEsKueryFi - {error && } + {error && } diff --git a/x-pack/legacy/plugins/uptime/public/pages/page_header.tsx b/x-pack/legacy/plugins/uptime/public/pages/page_header.tsx index 49e6ddb56602ca..b10bc6ba44f8a6 100644 --- a/x-pack/legacy/plugins/uptime/public/pages/page_header.tsx +++ b/x-pack/legacy/plugins/uptime/public/pages/page_header.tsx @@ -8,9 +8,9 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiSpacer, EuiButtonEmpty } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { Link } from 'react-router-dom'; -import { UptimeDatePicker } from '../components/functional/uptime_date_picker'; +import { UptimeDatePicker } from '../components/common/uptime_date_picker'; import { SETTINGS_ROUTE } from '../../common/constants'; -import { ToggleAlertFlyoutButton } from '../components/connected'; +import { ToggleAlertFlyoutButton } from '../components/overview/alerts/alerts_containers'; interface PageHeaderProps { headingText: string; diff --git a/x-pack/legacy/plugins/uptime/public/routes.tsx b/x-pack/legacy/plugins/uptime/public/routes.tsx index bb0700287dbf1e..b5e20ef8a70a9b 100644 --- a/x-pack/legacy/plugins/uptime/public/routes.tsx +++ b/x-pack/legacy/plugins/uptime/public/routes.tsx @@ -7,7 +7,7 @@ import React, { FC } from 'react'; import { Route, Switch } from 'react-router-dom'; import { DataPublicPluginSetup } from '../../../../../src/plugins/data/public'; -import { OverviewPage } from './components/connected/pages/overview_container'; +import { OverviewPage } from './components/overview/overview_container'; import { MONITOR_ROUTE, OVERVIEW_ROUTE, SETTINGS_ROUTE } from '../common/constants'; import { MonitorPage, NotFoundPage, SettingsPage } from './pages'; diff --git a/x-pack/legacy/plugins/uptime/public/state/api/monitor.ts b/x-pack/legacy/plugins/uptime/public/state/api/monitor.ts index b36eccca98da92..c3d0a0180cf514 100644 --- a/x-pack/legacy/plugins/uptime/public/state/api/monitor.ts +++ b/x-pack/legacy/plugins/uptime/public/state/api/monitor.ts @@ -8,7 +8,7 @@ import { BaseParams } from './types'; import { MonitorDetailsType, MonitorLocationsType } from '../../../common/runtime_types'; import { QueryParams } from '../actions/types'; import { apiService } from './utils'; -import { API_URLS } from '../../../common/constants/rest_api'; +import { API_URLS } from '../../../common/constants'; interface ApiRequest { monitorId: string; diff --git a/x-pack/legacy/plugins/uptime/public/state/api/monitor_duration.ts b/x-pack/legacy/plugins/uptime/public/state/api/monitor_duration.ts index daf725119fcf31..91034f1784b152 100644 --- a/x-pack/legacy/plugins/uptime/public/state/api/monitor_duration.ts +++ b/x-pack/legacy/plugins/uptime/public/state/api/monitor_duration.ts @@ -6,7 +6,7 @@ import { BaseParams } from './types'; import { apiService } from './utils'; -import { API_URLS } from '../../../common/constants/rest_api'; +import { API_URLS } from '../../../common/constants'; export const fetchMonitorDuration = async ({ monitorId, dateStart, dateEnd }: BaseParams) => { const queryParams = { diff --git a/x-pack/legacy/plugins/uptime/public/state/api/overview_filters.ts b/x-pack/legacy/plugins/uptime/public/state/api/overview_filters.ts index 9943bc27f11f02..6330d8a912210d 100644 --- a/x-pack/legacy/plugins/uptime/public/state/api/overview_filters.ts +++ b/x-pack/legacy/plugins/uptime/public/state/api/overview_filters.ts @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { GetOverviewFiltersPayload } from '../actions/overview_filters'; +import { GetOverviewFiltersPayload } from '../actions'; import { OverviewFiltersType } from '../../../common/runtime_types'; import { apiService } from './utils'; -import { API_URLS } from '../../../common/constants/rest_api'; +import { API_URLS } from '../../../common/constants'; export const fetchOverviewFilters = async ({ dateRangeStart, diff --git a/x-pack/legacy/plugins/uptime/public/state/api/ping.ts b/x-pack/legacy/plugins/uptime/public/state/api/ping.ts index bbd3ddf399dcc6..6de27879a49f58 100644 --- a/x-pack/legacy/plugins/uptime/public/state/api/ping.ts +++ b/x-pack/legacy/plugins/uptime/public/state/api/ping.ts @@ -13,7 +13,7 @@ import { HistogramResult, } from '../../../common/runtime_types'; import { apiService } from './utils'; -import { API_URLS } from '../../../common/constants/rest_api'; +import { API_URLS } from '../../../common/constants'; export const fetchPings: APIFn = async ({ dateRange: { from, to }, diff --git a/x-pack/legacy/plugins/uptime/public/state/api/snapshot.ts b/x-pack/legacy/plugins/uptime/public/state/api/snapshot.ts index e663d0241d6886..9ee53dd2cbcef7 100644 --- a/x-pack/legacy/plugins/uptime/public/state/api/snapshot.ts +++ b/x-pack/legacy/plugins/uptime/public/state/api/snapshot.ts @@ -6,7 +6,7 @@ import { SnapshotType, Snapshot } from '../../../common/runtime_types'; import { apiService } from './utils'; -import { API_URLS } from '../../../common/constants/rest_api'; +import { API_URLS } from '../../../common/constants'; export interface SnapShotQueryParams { dateRangeStart: string; diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/monitor_status.ts b/x-pack/legacy/plugins/uptime/public/state/reducers/monitor_status.ts index fa3e377b5ebf4f..a98e89a27a7110 100644 --- a/x-pack/legacy/plugins/uptime/public/state/reducers/monitor_status.ts +++ b/x-pack/legacy/plugins/uptime/public/state/reducers/monitor_status.ts @@ -26,7 +26,7 @@ type MonitorStatusPayload = QueryParams & Ping; export const monitorStatusReducer = handleActions( { - [String(getMonitorStatusAction)]: (state, action: Action) => ({ + [String(getMonitorStatusAction)]: state => ({ ...state, loading: true, }), @@ -43,7 +43,7 @@ export const monitorStatusReducer = handleActions) => ({ + [String(getMonitorStatusActionFail)]: state => ({ ...state, loading: false, }), diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/ui.ts b/x-pack/legacy/plugins/uptime/public/state/reducers/ui.ts index 702d314250521f..c533f293fc940a 100644 --- a/x-pack/legacy/plugins/uptime/public/state/reducers/ui.ts +++ b/x-pack/legacy/plugins/uptime/public/state/reducers/ui.ts @@ -13,7 +13,7 @@ import { triggerAppRefresh, UiPayload, setAlertFlyoutVisible, -} from '../actions/ui'; +} from '../actions'; export interface UiState { alertFlyoutVisible: boolean; diff --git a/x-pack/legacy/plugins/uptime/public/state/selectors/index.ts b/x-pack/legacy/plugins/uptime/public/state/selectors/index.ts index dc5df3f93804db..7260c61f441473 100644 --- a/x-pack/legacy/plugins/uptime/public/state/selectors/index.ts +++ b/x-pack/legacy/plugins/uptime/public/state/selectors/index.ts @@ -46,6 +46,16 @@ export const selectPingList = ({ pingList, ui: { lastRefresh } }: AppState) => ( lastRefresh, }); +export const snapshotDataSelector = ({ + snapshot: { count, loading }, + ui: { lastRefresh, esKuery }, +}: AppState) => ({ + count, + lastRefresh, + loading, + esKuery, +}); + const mlCapabilitiesSelector = (state: AppState) => state.ml.mlCapabilities.data; export const hasMLFeatureAvailable = createSelector( diff --git a/x-pack/legacy/plugins/uptime/public/uptime_app.tsx b/x-pack/legacy/plugins/uptime/public/uptime_app.tsx index 556e5b9bf299ed..92775a26638633 100644 --- a/x-pack/legacy/plugins/uptime/public/uptime_app.tsx +++ b/x-pack/legacy/plugins/uptime/public/uptime_app.tsx @@ -18,12 +18,14 @@ import { UptimeSettingsContextProvider, UptimeThemeContextProvider, } from './contexts'; -import { CommonlyUsedRange } from './components/functional/uptime_date_picker'; +import { CommonlyUsedRange } from './components/common/uptime_date_picker'; import { store } from './state'; import { setBasePath } from './state/actions'; import { PageRouter } from './routes'; -import { UptimeAlertsFlyoutWrapper } from './components/connected'; -import { UptimeAlertsContextProvider } from './components/functional/alerts'; +import { + UptimeAlertsContextProvider, + UptimeAlertsFlyoutWrapper, +} from './components/overview/alerts'; import { kibanaService } from './state/kibana_service'; export interface UptimeAppColors { diff --git a/x-pack/package.json b/x-pack/package.json index a4fdb17f52fe55..3c6146b491f604 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -85,7 +85,7 @@ "@types/node-fetch": "^2.5.0", "@types/nodemailer": "^6.2.1", "@types/object-hash": "^1.3.0", - "@types/papaparse": "^4.5.11", + "@types/papaparse": "^5.0.3", "@types/pngjs": "^3.3.2", "@types/prop-types": "^15.5.3", "@types/proper-lockfile": "^3.0.1", @@ -290,7 +290,7 @@ "oboe": "^2.1.4", "oppsy": "^2.0.0", "p-retry": "^4.2.0", - "papaparse": "^4.6.3", + "papaparse": "^5.2.0", "pdfmake": "^0.1.63", "pluralize": "3.1.0", "pngjs": "3.4.0", diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/view/defs.tsx b/x-pack/plugins/endpoint/public/embeddables/resolver/view/defs.tsx index de9c3c7e8f8f3e..064645019ca34c 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/view/defs.tsx +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/view/defs.tsx @@ -54,7 +54,11 @@ type ResolverColorNames = | 'activeNoWarning' | 'activeWarning' | 'fullLabelBackground' - | 'inertDescription'; + | 'inertDescription' + | 'labelBackgroundTerminatedProcess' + | 'labelBackgroundTerminatedTrigger' + | 'labelBackgroundRunningProcess' + | 'labelBackgroundRunningTrigger'; export const NamedColors: Record = { ok: saturate(0.5, resolverPalette.temperatures[0]), @@ -70,6 +74,10 @@ export const NamedColors: Record = { activeNoWarning: '#0078FF', activeWarning: '#C61F38', fullLabelBackground: '#3B3C41', + labelBackgroundTerminatedProcess: '#8A96A8', + labelBackgroundTerminatedTrigger: '#8A96A8', + labelBackgroundRunningProcess: '#8A96A8', + labelBackgroundRunningTrigger: '#8A96A8', inertDescription: '#747474', }; diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/view/process_event_dot.tsx b/x-pack/plugins/endpoint/public/embeddables/resolver/view/process_event_dot.tsx index 10e331ffff02d5..3201e83164dba6 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/view/process_event_dot.tsx +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/view/process_event_dot.tsx @@ -7,7 +7,13 @@ import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; import { i18n } from '@kbn/i18n'; -import { htmlIdGenerator, EuiKeyboardAccessible } from '@elastic/eui'; +import { + htmlIdGenerator, + EuiKeyboardAccessible, + EuiButton, + EuiFlexGroup, + EuiFlexItem, +} from '@elastic/eui'; import { useSelector } from 'react-redux'; import { applyMatrix3 } from '../lib/vector2'; import { Vector2, Matrix3, AdjacentProcessMap, ResolverProcessType } from '../types'; @@ -21,7 +27,7 @@ import * as selectors from '../store/selectors'; const nodeAssets = { runningProcessCube: { cubeSymbol: `#${SymbolIds.runningProcessCube}`, - labelBackground: NamedColors.fullLabelBackground, + labelBackground: NamedColors.labelBackgroundRunningProcess, descriptionFill: NamedColors.empty, descriptionText: i18n.translate('xpack.endpoint.resolver.runningProcess', { defaultMessage: 'Running Process', @@ -29,7 +35,7 @@ const nodeAssets = { }, runningTriggerCube: { cubeSymbol: `#${SymbolIds.runningTriggerCube}`, - labelBackground: NamedColors.fullLabelBackground, + labelBackground: NamedColors.labelBackgroundRunningTrigger, descriptionFill: NamedColors.empty, descriptionText: i18n.translate('xpack.endpoint.resolver.runningTrigger', { defaultMessage: 'Running Trigger', @@ -37,7 +43,7 @@ const nodeAssets = { }, terminatedProcessCube: { cubeSymbol: `#${SymbolIds.terminatedProcessCube}`, - labelBackground: NamedColors.fullLabelBackground, + labelBackground: NamedColors.labelBackgroundTerminatedProcess, descriptionFill: NamedColors.empty, descriptionText: i18n.translate('xpack.endpoint.resolver.terminatedProcess', { defaultMessage: 'Terminated Process', @@ -45,7 +51,7 @@ const nodeAssets = { }, terminatedTriggerCube: { cubeSymbol: `#${SymbolIds.terminatedTriggerCube}`, - labelBackground: NamedColors.fullLabelBackground, + labelBackground: NamedColors.labelBackgroundTerminatedTrigger, descriptionFill: NamedColors.empty, descriptionText: i18n.translate('xpack.endpoint.resolver.terminatedTrigger', { defaultMessage: 'Terminated Trigger', @@ -53,8 +59,46 @@ const nodeAssets = { }, }; +const ChildEventsButton = React.memo(() => { + return ( + ) => { + clickEvent.preventDefault(); + clickEvent.stopPropagation(); + }, [])} + color="ghost" + size="s" + iconType="arrowDown" + iconSide="right" + tabIndex={-1} + > + {i18n.translate('xpack.endpoint.resolver.relatedEvents', { + defaultMessage: 'Events', + })} + + ); +}); + +const RelatedAlertsButton = React.memo(() => { + return ( + ) => { + clickEvent.preventDefault(); + clickEvent.stopPropagation(); + }, [])} + color="ghost" + size="s" + tabIndex={-1} + > + {i18n.translate('xpack.endpoint.resolver.relatedAlerts', { + defaultMessage: 'Related Alerts', + })} + + ); +}); + /** - * A placeholder view for a process node. + * An artefact that represents a process node. */ export const ProcessEventDot = styled( React.memo( @@ -184,6 +228,7 @@ export const ProcessEventDot = styled( }, [animationTarget, dispatch, nodeId] ); + /* eslint-disable jsx-a11y/click-events-have-key-events */ /** * Key event handling (e.g. 'Enter'/'Space') is provisioned by the `EuiKeyboardAccessible` component @@ -256,13 +301,17 @@ export const ProcessEventDot = styled(
{descriptionText}
= 2 ? 'euiButton' : 'euiButton euiButton--small'} data-test-subject="nodeLabel" id={labelId} style={{ backgroundColor: labelBackground, - padding: '.15em 0', + padding: '.15rem 0', textAlign: 'center', - maxWidth: '100%', + maxWidth: '20rem', + minWidth: '12rem', + width: '60%', overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis', contain: 'content', + margin: '.25rem 0 .35rem 0', }} > - {eventModel.eventName(event)} + + {eventModel.eventName(event)} +
+ {magFactorX >= 2 && ( + + + + + + + + + )}
@@ -317,6 +383,8 @@ export const ProcessEventDot = styled( white-space: nowrap; will-change: left, top, width, height; contain: strict; + min-width: 280px; + min-height: 90px; //dasharray & dashoffset should be equal to "pull" the stroke back //when it is transitioned. diff --git a/x-pack/plugins/endpoint/scripts/resolver_generator.ts b/x-pack/plugins/endpoint/scripts/resolver_generator.ts index dd9e591f4b034f..2129bef0624b87 100644 --- a/x-pack/plugins/endpoint/scripts/resolver_generator.ts +++ b/x-pack/plugins/endpoint/scripts/resolver_generator.ts @@ -29,7 +29,7 @@ async function main() { alertIndex: { alias: 'ai', describe: 'index to store alerts in', - default: '.alerts-endpoint-000001', + default: 'events-endpoint-1', type: 'string', }, eventIndex: { diff --git a/x-pack/plugins/infra/common/inventory_models/aws_ec2/layout.tsx b/x-pack/plugins/infra/common/inventory_models/aws_ec2/layout.tsx index 68bfe41fd538e6..9494e4aa396a50 100644 --- a/x-pack/plugins/infra/common/inventory_models/aws_ec2/layout.tsx +++ b/x-pack/plugins/infra/common/inventory_models/aws_ec2/layout.tsx @@ -6,19 +6,19 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LayoutPropsWithTheme } from '../../../public/pages/metrics/types'; +import { LayoutPropsWithTheme } from '../../../public/pages/metrics/metric_detail/types'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { Section } from '../../../public/pages/metrics/components/section'; +import { Section } from '../../../public/pages/metrics/metric_detail/components/section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { SubSection } from '../../../public/pages/metrics/components/sub_section'; +import { SubSection } from '../../../public/pages/metrics/metric_detail/components/sub_section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LayoutContent } from '../../../public/pages/metrics/components/layout_content'; +import { LayoutContent } from '../../../public/pages/metrics/metric_detail/components/layout_content'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ChartSectionVis } from '../../../public/pages/metrics/components/chart_section_vis'; +import { ChartSectionVis } from '../../../public/pages/metrics/metric_detail/components/chart_section_vis'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { withTheme } from '../../../../observability/public'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { MetadataDetails } from '../../../public/pages/metrics/components/metadata_details'; +import { MetadataDetails } from '../../../public/pages/metrics/metric_detail/components/metadata_details'; export const Layout = withTheme(({ metrics, theme, onChangeRangeTime }: LayoutPropsWithTheme) => ( diff --git a/x-pack/plugins/infra/common/inventory_models/aws_ec2/toolbar_items.tsx b/x-pack/plugins/infra/common/inventory_models/aws_ec2/toolbar_items.tsx index 683851fec4d772..b2da7dec3f2e08 100644 --- a/x-pack/plugins/infra/common/inventory_models/aws_ec2/toolbar_items.tsx +++ b/x-pack/plugins/infra/common/inventory_models/aws_ec2/toolbar_items.tsx @@ -6,9 +6,9 @@ import React from 'react'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ToolbarProps } from '../../../public/components/inventory/toolbars/toolbar'; -import { MetricsAndGroupByToolbarItems } from '../shared/compontents/metrics_and_groupby_toolbar_items'; -import { CloudToolbarItems } from '../shared/compontents/cloud_toolbar_items'; +import { ToolbarProps } from '../../../public/pages/metrics/inventory_view/components/toolbars/toolbar'; +import { MetricsAndGroupByToolbarItems } from '../shared/components/metrics_and_groupby_toolbar_items'; +import { CloudToolbarItems } from '../shared/components/cloud_toolbar_items'; import { SnapshotMetricType } from '../types'; export const AwsEC2ToolbarItems = (props: ToolbarProps) => { diff --git a/x-pack/plugins/infra/common/inventory_models/aws_rds/layout.tsx b/x-pack/plugins/infra/common/inventory_models/aws_rds/layout.tsx index 220c6c67f4aeaa..08b865f01b06c6 100644 --- a/x-pack/plugins/infra/common/inventory_models/aws_rds/layout.tsx +++ b/x-pack/plugins/infra/common/inventory_models/aws_rds/layout.tsx @@ -6,17 +6,17 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LayoutPropsWithTheme } from '../../../public/pages/metrics/types'; +import { LayoutPropsWithTheme } from '../../../public/pages/metrics/metric_detail/types'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { Section } from '../../../public/pages/metrics/components/section'; +import { Section } from '../../../public/pages/metrics/metric_detail/components/section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { SubSection } from '../../../public/pages/metrics/components/sub_section'; +import { SubSection } from '../../../public/pages/metrics/metric_detail/components/sub_section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ChartSectionVis } from '../../../public/pages/metrics/components/chart_section_vis'; +import { ChartSectionVis } from '../../../public/pages/metrics/metric_detail/components/chart_section_vis'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { withTheme } from '../../../../observability/public'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LayoutContent } from '../../../public/pages/metrics/components/layout_content'; +import { LayoutContent } from '../../../public/pages/metrics/metric_detail/components/layout_content'; export const Layout = withTheme(({ metrics, onChangeRangeTime, theme }: LayoutPropsWithTheme) => ( diff --git a/x-pack/plugins/infra/common/inventory_models/aws_rds/toolbar_items.tsx b/x-pack/plugins/infra/common/inventory_models/aws_rds/toolbar_items.tsx index 24f05fd91589c8..2a8394b9dd3a41 100644 --- a/x-pack/plugins/infra/common/inventory_models/aws_rds/toolbar_items.tsx +++ b/x-pack/plugins/infra/common/inventory_models/aws_rds/toolbar_items.tsx @@ -6,9 +6,9 @@ import React from 'react'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ToolbarProps } from '../../../public/components/inventory/toolbars/toolbar'; -import { MetricsAndGroupByToolbarItems } from '../shared/compontents/metrics_and_groupby_toolbar_items'; -import { CloudToolbarItems } from '../shared/compontents/cloud_toolbar_items'; +import { ToolbarProps } from '../../../public/pages/metrics/inventory_view/components/toolbars/toolbar'; +import { MetricsAndGroupByToolbarItems } from '../shared/components/metrics_and_groupby_toolbar_items'; +import { CloudToolbarItems } from '../shared/components/cloud_toolbar_items'; import { SnapshotMetricType } from '../types'; export const AwsRDSToolbarItems = (props: ToolbarProps) => { diff --git a/x-pack/plugins/infra/common/inventory_models/aws_s3/layout.tsx b/x-pack/plugins/infra/common/inventory_models/aws_s3/layout.tsx index 805236cf470827..e16f8ef6addde6 100644 --- a/x-pack/plugins/infra/common/inventory_models/aws_s3/layout.tsx +++ b/x-pack/plugins/infra/common/inventory_models/aws_s3/layout.tsx @@ -6,17 +6,17 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LayoutPropsWithTheme } from '../../../public/pages/metrics/types'; +import { LayoutPropsWithTheme } from '../../../public/pages/metrics/metric_detail/types'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { Section } from '../../../public/pages/metrics/components/section'; +import { Section } from '../../../public/pages/metrics/metric_detail/components/section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { SubSection } from '../../../public/pages/metrics/components/sub_section'; +import { SubSection } from '../../../public/pages/metrics/metric_detail/components/sub_section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ChartSectionVis } from '../../../public/pages/metrics/components/chart_section_vis'; +import { ChartSectionVis } from '../../../public/pages/metrics/metric_detail/components/chart_section_vis'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { withTheme } from '../../../../observability/public'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LayoutContent } from '../../../public/pages/metrics/components/layout_content'; +import { LayoutContent } from '../../../public/pages/metrics/metric_detail/components/layout_content'; export const Layout = withTheme(({ metrics, onChangeRangeTime, theme }: LayoutPropsWithTheme) => ( diff --git a/x-pack/plugins/infra/common/inventory_models/aws_s3/toolbar_items.tsx b/x-pack/plugins/infra/common/inventory_models/aws_s3/toolbar_items.tsx index 54c3196ae28335..324bdd05860290 100644 --- a/x-pack/plugins/infra/common/inventory_models/aws_s3/toolbar_items.tsx +++ b/x-pack/plugins/infra/common/inventory_models/aws_s3/toolbar_items.tsx @@ -6,9 +6,9 @@ import React from 'react'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ToolbarProps } from '../../../public/components/inventory/toolbars/toolbar'; -import { MetricsAndGroupByToolbarItems } from '../shared/compontents/metrics_and_groupby_toolbar_items'; -import { CloudToolbarItems } from '../shared/compontents/cloud_toolbar_items'; +import { ToolbarProps } from '../../../public/pages/metrics/inventory_view/components/toolbars/toolbar'; +import { MetricsAndGroupByToolbarItems } from '../shared/components/metrics_and_groupby_toolbar_items'; +import { CloudToolbarItems } from '../shared/components/cloud_toolbar_items'; import { SnapshotMetricType } from '../types'; export const AwsS3ToolbarItems = (props: ToolbarProps) => { diff --git a/x-pack/plugins/infra/common/inventory_models/aws_sqs/layout.tsx b/x-pack/plugins/infra/common/inventory_models/aws_sqs/layout.tsx index d581ac751682d5..ff13f2db104de9 100644 --- a/x-pack/plugins/infra/common/inventory_models/aws_sqs/layout.tsx +++ b/x-pack/plugins/infra/common/inventory_models/aws_sqs/layout.tsx @@ -6,17 +6,17 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LayoutPropsWithTheme } from '../../../public/pages/metrics/types'; +import { LayoutPropsWithTheme } from '../../../public/pages/metrics/metric_detail/types'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { Section } from '../../../public/pages/metrics/components/section'; +import { Section } from '../../../public/pages/metrics/metric_detail/components/section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { SubSection } from '../../../public/pages/metrics/components/sub_section'; +import { SubSection } from '../../../public/pages/metrics/metric_detail/components/sub_section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ChartSectionVis } from '../../../public/pages/metrics/components/chart_section_vis'; +import { ChartSectionVis } from '../../../public/pages/metrics/metric_detail/components/chart_section_vis'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { withTheme } from '../../../../observability/public'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LayoutContent } from '../../../public/pages/metrics/components/layout_content'; +import { LayoutContent } from '../../../public/pages/metrics/metric_detail/components/layout_content'; export const Layout = withTheme(({ metrics, onChangeRangeTime, theme }: LayoutPropsWithTheme) => ( diff --git a/x-pack/plugins/infra/common/inventory_models/aws_sqs/toolbar_items.tsx b/x-pack/plugins/infra/common/inventory_models/aws_sqs/toolbar_items.tsx index 22cb2740a4a7f7..3229c07034772c 100644 --- a/x-pack/plugins/infra/common/inventory_models/aws_sqs/toolbar_items.tsx +++ b/x-pack/plugins/infra/common/inventory_models/aws_sqs/toolbar_items.tsx @@ -6,9 +6,9 @@ import React from 'react'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ToolbarProps } from '../../../public/components/inventory/toolbars/toolbar'; -import { MetricsAndGroupByToolbarItems } from '../shared/compontents/metrics_and_groupby_toolbar_items'; -import { CloudToolbarItems } from '../shared/compontents/cloud_toolbar_items'; +import { ToolbarProps } from '../../../public/pages/metrics/inventory_view/components/toolbars/toolbar'; +import { MetricsAndGroupByToolbarItems } from '../shared/components/metrics_and_groupby_toolbar_items'; +import { CloudToolbarItems } from '../shared/components/cloud_toolbar_items'; import { SnapshotMetricType } from '../types'; export const AwsSQSToolbarItems = (props: ToolbarProps) => { diff --git a/x-pack/plugins/infra/common/inventory_models/container/layout.tsx b/x-pack/plugins/infra/common/inventory_models/container/layout.tsx index 9956b2c9a2ce46..b9366a43e40c6b 100644 --- a/x-pack/plugins/infra/common/inventory_models/container/layout.tsx +++ b/x-pack/plugins/infra/common/inventory_models/container/layout.tsx @@ -6,21 +6,21 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LayoutPropsWithTheme } from '../../../public/pages/metrics/types'; +import { LayoutPropsWithTheme } from '../../../public/pages/metrics/metric_detail/types'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { Section } from '../../../public/pages/metrics/components/section'; +import { Section } from '../../../public/pages/metrics/metric_detail/components/section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { SubSection } from '../../../public/pages/metrics/components/sub_section'; +import { SubSection } from '../../../public/pages/metrics/metric_detail/components/sub_section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { GaugesSectionVis } from '../../../public/pages/metrics/components/gauges_section_vis'; +import { GaugesSectionVis } from '../../../public/pages/metrics/metric_detail/components/gauges_section_vis'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ChartSectionVis } from '../../../public/pages/metrics/components/chart_section_vis'; +import { ChartSectionVis } from '../../../public/pages/metrics/metric_detail/components/chart_section_vis'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { withTheme } from '../../../../observability/public'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LayoutContent } from '../../../public/pages/metrics/components/layout_content'; +import { LayoutContent } from '../../../public/pages/metrics/metric_detail/components/layout_content'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { MetadataDetails } from '../../../public/pages/metrics/components/metadata_details'; +import { MetadataDetails } from '../../../public/pages/metrics/metric_detail/components/metadata_details'; export const Layout = withTheme(({ metrics, onChangeRangeTime, theme }: LayoutPropsWithTheme) => ( diff --git a/x-pack/plugins/infra/common/inventory_models/container/toolbar_items.tsx b/x-pack/plugins/infra/common/inventory_models/container/toolbar_items.tsx index dbb77cb3b677ee..f6c707726d9ca1 100644 --- a/x-pack/plugins/infra/common/inventory_models/container/toolbar_items.tsx +++ b/x-pack/plugins/infra/common/inventory_models/container/toolbar_items.tsx @@ -6,8 +6,8 @@ import React from 'react'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ToolbarProps } from '../../../public/components/inventory/toolbars/toolbar'; -import { MetricsAndGroupByToolbarItems } from '../shared/compontents/metrics_and_groupby_toolbar_items'; +import { ToolbarProps } from '../../../public/pages/metrics/inventory_view/components/toolbars/toolbar'; +import { MetricsAndGroupByToolbarItems } from '../shared/components/metrics_and_groupby_toolbar_items'; import { SnapshotMetricType } from '../types'; export const ContainerToolbarItems = (props: ToolbarProps) => { diff --git a/x-pack/plugins/infra/common/inventory_models/host/layout.tsx b/x-pack/plugins/infra/common/inventory_models/host/layout.tsx index 6d7d3612542208..e23118c747a9ba 100644 --- a/x-pack/plugins/infra/common/inventory_models/host/layout.tsx +++ b/x-pack/plugins/infra/common/inventory_models/host/layout.tsx @@ -8,21 +8,21 @@ import { i18n } from '@kbn/i18n'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { withTheme } from '../../../../observability/public'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LayoutPropsWithTheme } from '../../../public/pages/metrics/types'; +import { LayoutPropsWithTheme } from '../../../public/pages/metrics/metric_detail/types'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { Section } from '../../../public/pages/metrics/components/section'; +import { Section } from '../../../public/pages/metrics/metric_detail/components/section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { SubSection } from '../../../public/pages/metrics/components/sub_section'; +import { SubSection } from '../../../public/pages/metrics/metric_detail/components/sub_section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { GaugesSectionVis } from '../../../public/pages/metrics/components/gauges_section_vis'; +import { GaugesSectionVis } from '../../../public/pages/metrics/metric_detail/components/gauges_section_vis'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ChartSectionVis } from '../../../public/pages/metrics/components/chart_section_vis'; +import { ChartSectionVis } from '../../../public/pages/metrics/metric_detail/components/chart_section_vis'; import * as Aws from '../shared/layouts/aws'; import * as Ngnix from '../shared/layouts/nginx'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { MetadataDetails } from '../../../public/pages/metrics/components/metadata_details'; +import { MetadataDetails } from '../../../public/pages/metrics/metric_detail/components/metadata_details'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LayoutContent } from '../../../public/pages/metrics/components/layout_content'; +import { LayoutContent } from '../../../public/pages/metrics/metric_detail/components/layout_content'; export const Layout = withTheme(({ metrics, onChangeRangeTime, theme }: LayoutPropsWithTheme) => ( diff --git a/x-pack/plugins/infra/common/inventory_models/host/toolbar_items.tsx b/x-pack/plugins/infra/common/inventory_models/host/toolbar_items.tsx index fc7696ee53c9d6..136264c0e26f4d 100644 --- a/x-pack/plugins/infra/common/inventory_models/host/toolbar_items.tsx +++ b/x-pack/plugins/infra/common/inventory_models/host/toolbar_items.tsx @@ -6,8 +6,8 @@ import React from 'react'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ToolbarProps } from '../../../public/components/inventory/toolbars/toolbar'; -import { MetricsAndGroupByToolbarItems } from '../shared/compontents/metrics_and_groupby_toolbar_items'; +import { ToolbarProps } from '../../../public/pages/metrics/inventory_view/components/toolbars/toolbar'; +import { MetricsAndGroupByToolbarItems } from '../shared/components/metrics_and_groupby_toolbar_items'; import { SnapshotMetricType } from '../types'; export const HostToolbarItems = (props: ToolbarProps) => { diff --git a/x-pack/plugins/infra/common/inventory_models/layouts.ts b/x-pack/plugins/infra/common/inventory_models/layouts.ts index b59ce010361ecd..df82f154b47b3b 100644 --- a/x-pack/plugins/infra/common/inventory_models/layouts.ts +++ b/x-pack/plugins/infra/common/inventory_models/layouts.ts @@ -23,7 +23,7 @@ import { Layout as AwsRDSLayout } from './aws_rds/layout'; import { Layout as AwsSQSLayout } from './aws_sqs/layout'; import { InventoryItemType } from './types'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LayoutProps } from '../../public/pages/metrics/types'; +import { LayoutProps } from '../../public/pages/metrics/metric_detail/types'; interface Layouts { [type: string]: ReactNode; diff --git a/x-pack/plugins/infra/common/inventory_models/pod/layout.tsx b/x-pack/plugins/infra/common/inventory_models/pod/layout.tsx index 8bc2f3ee8b4b31..271e32556ae286 100644 --- a/x-pack/plugins/infra/common/inventory_models/pod/layout.tsx +++ b/x-pack/plugins/infra/common/inventory_models/pod/layout.tsx @@ -6,22 +6,22 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LayoutPropsWithTheme } from '../../../public/pages/metrics/types'; +import { LayoutPropsWithTheme } from '../../../public/pages/metrics/metric_detail/types'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { Section } from '../../../public/pages/metrics/components/section'; +import { Section } from '../../../public/pages/metrics/metric_detail/components/section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { SubSection } from '../../../public/pages/metrics/components/sub_section'; +import { SubSection } from '../../../public/pages/metrics/metric_detail/components/sub_section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { GaugesSectionVis } from '../../../public/pages/metrics/components/gauges_section_vis'; +import { GaugesSectionVis } from '../../../public/pages/metrics/metric_detail/components/gauges_section_vis'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ChartSectionVis } from '../../../public/pages/metrics/components/chart_section_vis'; +import { ChartSectionVis } from '../../../public/pages/metrics/metric_detail/components/chart_section_vis'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { withTheme } from '../../../../observability/public'; import * as Nginx from '../shared/layouts/nginx'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { MetadataDetails } from '../../../public/pages/metrics/components/metadata_details'; +import { MetadataDetails } from '../../../public/pages/metrics/metric_detail/components/metadata_details'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LayoutContent } from '../../../public/pages/metrics/components/layout_content'; +import { LayoutContent } from '../../../public/pages/metrics/metric_detail/components/layout_content'; export const Layout = withTheme(({ metrics, onChangeRangeTime, theme }: LayoutPropsWithTheme) => ( diff --git a/x-pack/plugins/infra/common/inventory_models/pod/toolbar_items.tsx b/x-pack/plugins/infra/common/inventory_models/pod/toolbar_items.tsx index d48c27efd88fda..c1cd375ff47bf9 100644 --- a/x-pack/plugins/infra/common/inventory_models/pod/toolbar_items.tsx +++ b/x-pack/plugins/infra/common/inventory_models/pod/toolbar_items.tsx @@ -6,8 +6,8 @@ import React from 'react'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ToolbarProps } from '../../../public/components/inventory/toolbars/toolbar'; -import { MetricsAndGroupByToolbarItems } from '../shared/compontents/metrics_and_groupby_toolbar_items'; +import { ToolbarProps } from '../../../public/pages/metrics/inventory_view/components/toolbars/toolbar'; +import { MetricsAndGroupByToolbarItems } from '../shared/components/metrics_and_groupby_toolbar_items'; import { SnapshotMetricType } from '../types'; export const PodToolbarItems = (props: ToolbarProps) => { diff --git a/x-pack/plugins/infra/common/inventory_models/shared/compontents/cloud_toolbar_items.tsx b/x-pack/plugins/infra/common/inventory_models/shared/components/cloud_toolbar_items.tsx similarity index 75% rename from x-pack/plugins/infra/common/inventory_models/shared/compontents/cloud_toolbar_items.tsx rename to x-pack/plugins/infra/common/inventory_models/shared/components/cloud_toolbar_items.tsx index 766a8ae8142f57..da5017b0f3a36f 100644 --- a/x-pack/plugins/infra/common/inventory_models/shared/compontents/cloud_toolbar_items.tsx +++ b/x-pack/plugins/infra/common/inventory_models/shared/components/cloud_toolbar_items.tsx @@ -7,11 +7,11 @@ import React from 'react'; import { EuiFlexItem } from '@elastic/eui'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ToolbarProps } from '../../../../public/components/inventory/toolbars/toolbar'; +import { ToolbarProps } from '../../../../public/pages/metrics/inventory_view/components/toolbars/toolbar'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { WaffleAccountsControls } from '../../../../public/components/waffle/waffle_accounts_controls'; +import { WaffleAccountsControls } from '../../../../public/pages/metrics/inventory_view/components/waffle/waffle_accounts_controls'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { WaffleRegionControls } from '../../../../public/components/waffle/waffle_region_controls'; +import { WaffleRegionControls } from '../../../../public/pages/metrics/inventory_view/components/waffle/waffle_region_controls'; type Props = ToolbarProps; diff --git a/x-pack/plugins/infra/common/inventory_models/shared/compontents/metrics_and_groupby_toolbar_items.tsx b/x-pack/plugins/infra/common/inventory_models/shared/components/metrics_and_groupby_toolbar_items.tsx similarity index 81% rename from x-pack/plugins/infra/common/inventory_models/shared/compontents/metrics_and_groupby_toolbar_items.tsx rename to x-pack/plugins/infra/common/inventory_models/shared/components/metrics_and_groupby_toolbar_items.tsx index 738fce45ee99f1..bf37828ed0856f 100644 --- a/x-pack/plugins/infra/common/inventory_models/shared/compontents/metrics_and_groupby_toolbar_items.tsx +++ b/x-pack/plugins/infra/common/inventory_models/shared/components/metrics_and_groupby_toolbar_items.tsx @@ -7,16 +7,16 @@ import React, { useMemo } from 'react'; import { EuiFlexItem } from '@elastic/eui'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ToolbarProps } from '../../../../public/components/inventory/toolbars/toolbar'; +import { ToolbarProps } from '../../../../public/pages/metrics/inventory_view/components/toolbars/toolbar'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { WaffleMetricControls } from '../../../../public/components/waffle/metric_control'; +import { WaffleMetricControls } from '../../../../public/pages/metrics/inventory_view/components/waffle/metric_control'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { WaffleGroupByControls } from '../../../../public/components/waffle/waffle_group_by_controls'; +import { WaffleGroupByControls } from '../../../../public/pages/metrics/inventory_view/components/waffle/waffle_group_by_controls'; import { toGroupByOpt, toMetricOpt, // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../public/components/inventory/toolbars/toolbar_wrapper'; +} from '../../../../public/pages/metrics/inventory_view/components/toolbars/toolbar_wrapper'; import { SnapshotMetricType } from '../../types'; interface Props extends ToolbarProps { diff --git a/x-pack/plugins/infra/common/inventory_models/shared/layouts/aws.tsx b/x-pack/plugins/infra/common/inventory_models/shared/layouts/aws.tsx index 7a0b898d406ce7..6f2791534c17e8 100644 --- a/x-pack/plugins/infra/common/inventory_models/shared/layouts/aws.tsx +++ b/x-pack/plugins/infra/common/inventory_models/shared/layouts/aws.tsx @@ -6,15 +6,15 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LayoutPropsWithTheme } from '../../../../public/pages/metrics/types'; +import { LayoutPropsWithTheme } from '../../../../public/pages/metrics/metric_detail/types'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { Section } from '../../../../public/pages/metrics/components/section'; +import { Section } from '../../../../public/pages/metrics/metric_detail/components/section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { SubSection } from '../../../../public/pages/metrics/components/sub_section'; +import { SubSection } from '../../../../public/pages/metrics/metric_detail/components/sub_section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { GaugesSectionVis } from '../../../../public/pages/metrics/components/gauges_section_vis'; +import { GaugesSectionVis } from '../../../../public/pages/metrics/metric_detail/components/gauges_section_vis'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ChartSectionVis } from '../../../../public/pages/metrics/components/chart_section_vis'; +import { ChartSectionVis } from '../../../../public/pages/metrics/metric_detail/components/chart_section_vis'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { withTheme } from '../../../../../observability/public'; diff --git a/x-pack/plugins/infra/common/inventory_models/shared/layouts/nginx.tsx b/x-pack/plugins/infra/common/inventory_models/shared/layouts/nginx.tsx index 79cea5150d498d..cf3a06994cc96c 100644 --- a/x-pack/plugins/infra/common/inventory_models/shared/layouts/nginx.tsx +++ b/x-pack/plugins/infra/common/inventory_models/shared/layouts/nginx.tsx @@ -6,13 +6,13 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LayoutPropsWithTheme } from '../../../../public/pages/metrics/types'; +import { LayoutPropsWithTheme } from '../../../../public/pages/metrics/metric_detail/types'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { Section } from '../../../../public/pages/metrics/components/section'; +import { Section } from '../../../../public/pages/metrics/metric_detail/components/section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { SubSection } from '../../../../public/pages/metrics/components/sub_section'; +import { SubSection } from '../../../../public/pages/metrics/metric_detail/components/sub_section'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ChartSectionVis } from '../../../../public/pages/metrics/components/chart_section_vis'; +import { ChartSectionVis } from '../../../../public/pages/metrics/metric_detail/components/chart_section_vis'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { withTheme } from '../../../../../observability/public'; diff --git a/x-pack/plugins/infra/common/inventory_models/toolbars.ts b/x-pack/plugins/infra/common/inventory_models/toolbars.ts index 39e9f5a260f7a9..e00cb094d04550 100644 --- a/x-pack/plugins/infra/common/inventory_models/toolbars.ts +++ b/x-pack/plugins/infra/common/inventory_models/toolbars.ts @@ -11,7 +11,7 @@ import { HostToolbarItems } from './host/toolbar_items'; import { ContainerToolbarItems } from './container/toolbar_items'; import { PodToolbarItems } from './pod/toolbar_items'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ToolbarProps } from '../../public/components/inventory/toolbars/toolbar'; +import { ToolbarProps } from '../../public/pages/metrics/inventory_view/components/toolbars/toolbar'; import { AwsEC2ToolbarItems } from './aws_ec2/toolbar_items'; import { AwsS3ToolbarItems } from './aws_s3/toolbar_items'; import { AwsRDSToolbarItems } from './aws_rds/toolbar_items'; diff --git a/x-pack/plugins/infra/common/saved_objects/inventory_view.ts b/x-pack/plugins/infra/common/saved_objects/inventory_view.ts index 8ae765f379add1..8933de57b04485 100644 --- a/x-pack/plugins/infra/common/saved_objects/inventory_view.ts +++ b/x-pack/plugins/infra/common/saved_objects/inventory_view.ts @@ -7,7 +7,7 @@ // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { ElasticsearchMappingOf } from '../../server/utils/typed_elasticsearch_mappings'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { WaffleViewState } from '../../public/pages/inventory_view/hooks/use_waffle_view_state'; +import { WaffleViewState } from '../../public/pages/metrics/inventory_view/hooks/use_waffle_view_state'; export const inventoryViewSavedObjectType = 'inventory-view'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths diff --git a/x-pack/plugins/infra/common/saved_objects/metrics_explorer_view.ts b/x-pack/plugins/infra/common/saved_objects/metrics_explorer_view.ts index a9f11948446408..6eb08eabc15b5d 100644 --- a/x-pack/plugins/infra/common/saved_objects/metrics_explorer_view.ts +++ b/x-pack/plugins/infra/common/saved_objects/metrics_explorer_view.ts @@ -11,7 +11,7 @@ import { MetricsExplorerChartOptions, MetricsExplorerTimeOptions, // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../public/containers/metrics_explorer/use_metrics_explorer_options'; +} from '../../public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { SavedViewSavedObject } from '../../public/hooks/use_saved_view'; diff --git a/x-pack/plugins/infra/public/components/alerting/metrics/alert_flyout.tsx b/x-pack/plugins/infra/public/components/alerting/metrics/alert_flyout.tsx index 914054e1fd9b7e..38709c117c8176 100644 --- a/x-pack/plugins/infra/public/components/alerting/metrics/alert_flyout.tsx +++ b/x-pack/plugins/infra/public/components/alerting/metrics/alert_flyout.tsx @@ -10,8 +10,8 @@ import { TriggerActionsContext } from '../../../utils/triggers_actions_context'; import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { METRIC_THRESHOLD_ALERT_TYPE_ID } from '../../../../server/lib/alerting/metric_threshold/types'; -import { MetricsExplorerOptions } from '../../../containers/metrics_explorer/use_metrics_explorer_options'; import { MetricsExplorerSeries } from '../../../../common/http_api/metrics_explorer'; +import { MetricsExplorerOptions } from '../../../pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options'; interface Props { visible?: boolean; diff --git a/x-pack/plugins/infra/public/components/alerting/metrics/expression.tsx b/x-pack/plugins/infra/public/components/alerting/metrics/expression.tsx index 0e9da32aaa5093..665da25dcbfffd 100644 --- a/x-pack/plugins/infra/public/components/alerting/metrics/expression.tsx +++ b/x-pack/plugins/infra/public/components/alerting/metrics/expression.tsx @@ -35,10 +35,10 @@ import { IErrorObject } from '../../../../../triggers_actions_ui/public/types'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { AlertsContextValue } from '../../../../../triggers_actions_ui/public/application/context/alerts_context'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { MetricsExplorerOptions } from '../../../containers/metrics_explorer/use_metrics_explorer_options'; -import { MetricsExplorerKueryBar } from '../../metrics_explorer/kuery_bar'; import { MetricsExplorerSeries } from '../../../../common/http_api/metrics_explorer'; -import { MetricsExplorerGroupBy } from '../../metrics_explorer/group_by'; +import { MetricsExplorerKueryBar } from '../../../pages/metrics/metrics_explorer/components/kuery_bar'; +import { MetricsExplorerOptions } from '../../../pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options'; +import { MetricsExplorerGroupBy } from '../../../pages/metrics/metrics_explorer/components/group_by'; import { useSourceViaHttp } from '../../../containers/source/use_source_via_http'; interface AlertContextMeta { diff --git a/x-pack/plugins/infra/public/components/waffle/lib/type_guards.ts b/x-pack/plugins/infra/public/components/waffle/lib/type_guards.ts deleted file mode 100644 index f793afee1b948b..00000000000000 --- a/x-pack/plugins/infra/public/components/waffle/lib/type_guards.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { InfraWaffleMapGradientLegend, InfraWaffleMapStepLegend } from '../../../lib/lib'; - -export function isInfraWaffleMapStepLegend(subject: any): subject is InfraWaffleMapStepLegend { - return subject.type && subject.type === 'step'; -} - -export function isInfraWaffleMapGradientLegend( - subject: any -): subject is InfraWaffleMapGradientLegend { - return subject.type && subject.type === 'gradient'; -} diff --git a/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx b/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx index d2fa49e8d5d9fc..04f518aa9080fe 100644 --- a/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx +++ b/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx @@ -17,7 +17,7 @@ import { MetricsExplorerYAxisMode, MetricsExplorerChartType, MetricsExplorerChartOptions, -} from './use_metrics_explorer_options'; +} from '../../pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options'; interface MetricsExplorerUrlState { timerange?: MetricsExplorerTimeOptions; diff --git a/x-pack/plugins/infra/public/containers/with_options.tsx b/x-pack/plugins/infra/public/containers/with_options.tsx deleted file mode 100644 index e18fc85a68d60b..00000000000000 --- a/x-pack/plugins/infra/public/containers/with_options.tsx +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import moment from 'moment'; -import React from 'react'; - -import { euiPaletteColorBlind } from '@elastic/eui'; -import { InfraFormatterType, InfraOptions } from '../lib/lib'; -import { RendererFunction } from '../utils/typed_react'; - -const euiVisColorPalette = euiPaletteColorBlind(); - -const initialState = { - options: { - timerange: { - interval: '1m', - to: moment.utc().valueOf(), - from: moment - .utc() - .subtract(1, 'h') - .valueOf(), - }, - wafflemap: { - formatter: InfraFormatterType.percent, - formatTemplate: '{{value}}', - metric: { type: 'cpu' }, - groupBy: [], - legend: { - type: 'gradient', - rules: [ - { - value: 0, - color: '#D3DAE6', - }, - { - value: 1, - color: euiVisColorPalette[1], - }, - ], - }, - }, - } as InfraOptions, -}; - -interface WithOptionsProps { - children: RendererFunction; -} - -type State = Readonly; - -export const withOptions = (WrappedComponent: React.ComponentType) => ( - {args => } -); - -export class WithOptions extends React.Component { - public readonly state: State = initialState; - - public render() { - return this.props.children(this.state.options); - } -} diff --git a/x-pack/plugins/infra/public/pages/infrastructure/index.tsx b/x-pack/plugins/infra/public/pages/infrastructure/index.tsx deleted file mode 100644 index d592ae3480fc95..00000000000000 --- a/x-pack/plugins/infra/public/pages/infrastructure/index.tsx +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { i18n } from '@kbn/i18n'; - -import React from 'react'; -import { Route, RouteComponentProps, Switch } from 'react-router-dom'; - -import { EuiFlexItem, EuiFlexGroup } from '@elastic/eui'; -import { DocumentTitle } from '../../components/document_title'; -import { HelpCenterContent } from '../../components/help_center_content'; -import { RoutedTabs } from '../../components/navigation/routed_tabs'; -import { ColumnarPage } from '../../components/page'; -import { Header } from '../../components/header'; -import { MetricsExplorerOptionsContainer } from '../../containers/metrics_explorer/use_metrics_explorer_options'; -import { WithMetricsExplorerOptionsUrlState } from '../../containers/metrics_explorer/with_metrics_explorer_options_url_state'; -import { WithSource } from '../../containers/with_source'; -import { Source } from '../../containers/source'; -import { MetricsExplorerPage } from './metrics_explorer'; -import { SnapshotPage } from './snapshot'; -import { MetricsSettingsPage } from './settings'; -import { AppNavigation } from '../../components/navigation/app_navigation'; -import { SourceLoadingPage } from '../../components/source_loading_page'; -import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; -import { WaffleOptionsProvider } from '../inventory_view/hooks/use_waffle_options'; -import { WaffleTimeProvider } from '../inventory_view/hooks/use_waffle_time'; -import { WaffleFiltersProvider } from '../inventory_view/hooks/use_waffle_filters'; -import { AlertDropdown } from '../../components/alerting/metrics/alert_dropdown'; - -export const InfrastructurePage = ({ match }: RouteComponentProps) => { - const uiCapabilities = useKibana().services.application?.capabilities; - - return ( - - - - - - - - - -
- - - - - - - - - - - - - - ( - - {({ configuration, createDerivedIndexPattern }) => ( - - - {configuration ? ( - - ) : ( - - )} - - )} - - )} - /> - - - - - - - - ); -}; diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_host_detail_via_ip.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_host_detail_via_ip.tsx index b1dab3bd3f6737..3ad242c77412db 100644 --- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_host_detail_via_ip.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_host_detail_via_ip.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Redirect, RouteComponentProps } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; -import { replaceMetricTimeInQueryString } from '../metrics/hooks/use_metrics_time'; +import { replaceMetricTimeInQueryString } from '../metrics/metric_detail/hooks/use_metrics_time'; import { useHostIpToName } from './use_host_ip_to_name'; import { getFromFromLocation, getToFromLocation } from './query_params'; import { LoadingPage } from '../../components/loading_page'; diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_detail.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_detail.tsx index 72a41f5264244f..3d25e4c6c258d3 100644 --- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_detail.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_detail.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { Redirect, RouteComponentProps } from 'react-router-dom'; -import { replaceMetricTimeInQueryString } from '../metrics/hooks/use_metrics_time'; +import { replaceMetricTimeInQueryString } from '../metrics/metric_detail/hooks/use_metrics_time'; import { getFromFromLocation, getToFromLocation } from './query_params'; import { InventoryItemType } from '../../../common/inventory_models/types'; import { LinkDescriptor } from '../../hooks/use_link_props'; diff --git a/x-pack/plugins/infra/public/pages/metrics/index.tsx b/x-pack/plugins/infra/public/pages/metrics/index.tsx index 531be40d2dc43b..cc88dd9e0d0f8f 100644 --- a/x-pack/plugins/infra/public/pages/metrics/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/index.tsx @@ -3,138 +3,133 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + import { i18n } from '@kbn/i18n'; -import React, { useContext, useState } from 'react'; -import { euiStyled, EuiTheme, withTheme } from '../../../../observability/public'; + +import React from 'react'; +import { Route, RouteComponentProps, Switch } from 'react-router-dom'; + +import { EuiFlexItem, EuiFlexGroup } from '@elastic/eui'; import { DocumentTitle } from '../../components/document_title'; +import { HelpCenterContent } from '../../components/help_center_content'; +import { RoutedTabs } from '../../components/navigation/routed_tabs'; +import { ColumnarPage } from '../../components/page'; import { Header } from '../../components/header'; -import { ColumnarPage, PageContent } from '../../components/page'; -import { withMetricPageProviders } from './page_providers'; -import { useMetadata } from '../../containers/metadata/use_metadata'; +import { MetricsExplorerOptionsContainer } from './metrics_explorer/hooks/use_metrics_explorer_options'; +import { WithMetricsExplorerOptionsUrlState } from '../../containers/metrics_explorer/with_metrics_explorer_options_url_state'; +import { WithSource } from '../../containers/with_source'; import { Source } from '../../containers/source'; -import { InfraLoadingPanel } from '../../components/loading'; -import { findInventoryModel } from '../../../common/inventory_models'; -import { NavItem } from './lib/side_nav_context'; -import { NodeDetailsPage } from './components/node_details_page'; +import { MetricsExplorerPage } from './metrics_explorer'; +import { SnapshotPage } from './inventory_view'; +import { MetricsSettingsPage } from './settings'; +import { AppNavigation } from '../../components/navigation/app_navigation'; +import { SourceLoadingPage } from '../../components/source_loading_page'; import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; -import { InventoryItemType } from '../../../common/inventory_models/types'; -import { useMetricsTimeContext } from './hooks/use_metrics_time'; -import { useLinkProps } from '../../hooks/use_link_props'; - -const DetailPageContent = euiStyled(PageContent)` - overflow: auto; - background-color: ${props => props.theme.eui.euiColorLightestShade}; -`; - -interface Props { - theme: EuiTheme; - match: { - params: { - type: string; - node: string; - }; - }; -} - -export const MetricDetail = withMetricPageProviders( - withTheme(({ match }: Props) => { - const uiCapabilities = useKibana().services.application?.capabilities; - const nodeId = match.params.node; - const nodeType = match.params.type as InventoryItemType; - const inventoryModel = findInventoryModel(nodeType); - const { sourceId } = useContext(Source.Context); - const { - timeRange, - parsedTimeRange, - setTimeRange, - refreshInterval, - setRefreshInterval, - isAutoReloading, - setAutoReload, - triggerRefresh, - } = useMetricsTimeContext(); - const { - name, - filteredRequiredMetrics, - loading: metadataLoading, - cloudId, - metadata, - } = useMetadata(nodeId, nodeType, inventoryModel.requiredMetrics, sourceId, parsedTimeRange); - - const [sideNav, setSideNav] = useState([]); +import { WaffleOptionsProvider } from './inventory_view/hooks/use_waffle_options'; +import { WaffleTimeProvider } from './inventory_view/hooks/use_waffle_time'; +import { WaffleFiltersProvider } from './inventory_view/hooks/use_waffle_filters'; +import { AlertDropdown } from '../../components/alerting/metrics/alert_dropdown'; - const addNavItem = React.useCallback( - (item: NavItem) => { - if (!sideNav.some(n => n.id === item.id)) { - setSideNav([item, ...sideNav]); - } - }, - [sideNav] - ); +export const InfrastructurePage = ({ match }: RouteComponentProps) => { + const uiCapabilities = useKibana().services.application?.capabilities; - const metricsLinkProps = useLinkProps({ - app: 'metrics', - pathname: '/', - }); + return ( + + + + + + - const breadcrumbs = [ - { - ...metricsLinkProps, - text: i18n.translate('xpack.infra.header.infrastructureTitle', { - defaultMessage: 'Metrics', - }), - }, - { text: name }, - ]; + - if (metadataLoading && !filteredRequiredMetrics.length) { - return ( - - ); - } +
+ + + + + + + + + + - return ( - -
- - - {metadata ? ( - - ) : null} - - - ); - }) -); + + + ( + + {({ configuration, createDerivedIndexPattern }) => ( + + + {configuration ? ( + + ) : ( + + )} + + )} + + )} + /> + + + + + + + + ); +}; diff --git a/x-pack/plugins/infra/public/components/inventory/layout.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx similarity index 78% rename from x-pack/plugins/infra/public/components/inventory/layout.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx index 3c91f9fa5946fc..bc8be9862fe636 100644 --- a/x-pack/plugins/infra/public/components/inventory/layout.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx @@ -8,16 +8,16 @@ import React from 'react'; import { useInterval } from 'react-use'; import { euiPaletteColorBlind } from '@elastic/eui'; -import { NodesOverview } from '../nodes_overview'; +import { NodesOverview } from './nodes_overview'; import { Toolbar } from './toolbars/toolbar'; -import { PageContent } from '../page'; -import { useSnapshot } from '../../containers/waffle/use_snaphot'; -import { useInventoryMeta } from '../../containers/inventory_metadata/use_inventory_meta'; -import { useWaffleTimeContext } from '../../pages/inventory_view/hooks/use_waffle_time'; -import { useWaffleFiltersContext } from '../../pages/inventory_view/hooks/use_waffle_filters'; -import { useWaffleOptionsContext } from '../../pages/inventory_view/hooks/use_waffle_options'; -import { useSourceContext } from '../../containers/source'; -import { InfraFormatterType, InfraWaffleMapGradientLegend } from '../../lib/lib'; +import { PageContent } from '../../../../components/page'; +import { useSnapshot } from '../hooks/use_snaphot'; +import { useInventoryMeta } from '../hooks/use_inventory_meta'; +import { useWaffleTimeContext } from '../hooks/use_waffle_time'; +import { useWaffleFiltersContext } from '../hooks/use_waffle_filters'; +import { useWaffleOptionsContext } from '../hooks/use_waffle_options'; +import { useSourceContext } from '../../../../containers/source'; +import { InfraFormatterType, InfraWaffleMapGradientLegend } from '../../../../lib/lib'; const euiVisColorPalette = euiPaletteColorBlind(); diff --git a/x-pack/plugins/infra/public/components/nodes_overview/index.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/nodes_overview.tsx similarity index 88% rename from x-pack/plugins/infra/public/components/nodes_overview/index.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/nodes_overview.tsx index ef22e0486f8921..afbfd2a079253d 100644 --- a/x-pack/plugins/infra/public/components/nodes_overview/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/nodes_overview.tsx @@ -10,18 +10,25 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { get, max, min } from 'lodash'; import React from 'react'; -import { euiStyled } from '../../../../observability/public'; -import { InfraFormatterType, InfraWaffleMapBounds, InfraWaffleMapOptions } from '../../lib/lib'; -import { createFormatter } from '../../utils/formatters'; -import { NoData } from '../empty_states'; -import { InfraLoadingPanel } from '../loading'; -import { Map } from '../waffle/map'; -import { ViewSwitcher } from '../waffle/view_switcher'; -import { TableView } from './table'; -import { SnapshotNode, SnapshotCustomMetricInputRT } from '../../../common/http_api/snapshot_api'; -import { convertIntervalToString } from '../../utils/convert_interval_to_string'; -import { InventoryItemType } from '../../../common/inventory_models/types'; -import { createFormatterForMetric } from '../metrics_explorer/helpers/create_formatter_for_metric'; +import { euiStyled } from '../../../../../../observability/public'; +import { + InfraFormatterType, + InfraWaffleMapBounds, + InfraWaffleMapOptions, +} from '../../../../lib/lib'; +import { createFormatter } from '../../../../utils/formatters'; +import { NoData } from '../../../../components/empty_states'; +import { InfraLoadingPanel } from '../../../../components/loading'; +import { Map } from './waffle/map'; +import { ViewSwitcher } from './waffle/view_switcher'; +import { TableView } from './table_view'; +import { + SnapshotNode, + SnapshotCustomMetricInputRT, +} from '../../../../../common/http_api/snapshot_api'; +import { convertIntervalToString } from '../../../../utils/convert_interval_to_string'; +import { InventoryItemType } from '../../../../../common/inventory_models/types'; +import { createFormatterForMetric } from '../../metrics_explorer/components/helpers/create_formatter_for_metric'; export interface KueryFilterQuery { kind: 'kuery'; diff --git a/x-pack/plugins/infra/public/pages/inventory_view/compontents/search_bar.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/search_bar.tsx similarity index 86% rename from x-pack/plugins/infra/public/pages/inventory_view/compontents/search_bar.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/search_bar.tsx index f4fde46d434f83..1f84ef3685f342 100644 --- a/x-pack/plugins/infra/public/pages/inventory_view/compontents/search_bar.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/search_bar.tsx @@ -5,9 +5,9 @@ */ import React, { useContext } from 'react'; import { i18n } from '@kbn/i18n'; -import { Source } from '../../../containers/source'; -import { AutocompleteField } from '../../../components/autocomplete_field'; -import { WithKueryAutocompletion } from '../../../containers/with_kuery_autocompletion'; +import { Source } from '../../../../containers/source'; +import { AutocompleteField } from '../../../../components/autocomplete_field'; +import { WithKueryAutocompletion } from '../../../../containers/with_kuery_autocompletion'; import { useWaffleFiltersContext } from '../hooks/use_waffle_filters'; export const SearchBar = () => { diff --git a/x-pack/plugins/infra/public/components/nodes_overview/table.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/table_view.tsx similarity index 92% rename from x-pack/plugins/infra/public/components/nodes_overview/table.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/table_view.tsx index 82991076255eef..0557343e735f91 100644 --- a/x-pack/plugins/infra/public/components/nodes_overview/table.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/table_view.tsx @@ -9,13 +9,13 @@ import { i18n } from '@kbn/i18n'; import { last } from 'lodash'; import React, { useState, useCallback, useEffect } from 'react'; -import { createWaffleMapNode } from '../../containers/waffle/nodes_to_wafflemap'; -import { InfraWaffleMapNode, InfraWaffleMapOptions } from '../../lib/lib'; -import { fieldToName } from '../waffle/lib/field_to_display_name'; -import { NodeContextMenu } from '../waffle/node_context_menu'; -import { InventoryItemType } from '../../../common/inventory_models/types'; -import { SnapshotNode, SnapshotNodePath } from '../../../common/http_api/snapshot_api'; -import { CONTAINER_CLASSNAME } from '../../apps/start_app'; +import { createWaffleMapNode } from '../lib/nodes_to_wafflemap'; +import { InfraWaffleMapNode, InfraWaffleMapOptions } from '../../../../lib/lib'; +import { fieldToName } from '../lib/field_to_display_name'; +import { NodeContextMenu } from './waffle/node_context_menu'; +import { InventoryItemType } from '../../../../../common/inventory_models/types'; +import { SnapshotNode, SnapshotNodePath } from '../../../../../common/http_api/snapshot_api'; +import { CONTAINER_CLASSNAME } from '../../../../apps/start_app'; interface Props { nodes: SnapshotNode[]; diff --git a/x-pack/plugins/infra/public/components/inventory/toolbars/save_views.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/save_views.tsx similarity index 68% rename from x-pack/plugins/infra/public/components/inventory/toolbars/save_views.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/save_views.tsx index cb315d3e17b032..eb40ea595662a2 100644 --- a/x-pack/plugins/infra/public/components/inventory/toolbars/save_views.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/save_views.tsx @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ import React from 'react'; -import { SavedViewsToolbarControls } from '../../saved_views/toolbar_control'; -import { inventoryViewSavedObjectType } from '../../../../common/saved_objects/inventory_view'; -import { useWaffleViewState } from '../../../pages/inventory_view/hooks/use_waffle_view_state'; +import { SavedViewsToolbarControls } from '../../../../../components/saved_views/toolbar_control'; +import { inventoryViewSavedObjectType } from '../../../../../../common/saved_objects/inventory_view'; +import { useWaffleViewState } from '../../hooks/use_waffle_view_state'; export const SavedViews = () => { const { viewState, defaultViewState, onViewChange } = useWaffleViewState(); diff --git a/x-pack/plugins/infra/public/components/inventory/toolbars/toolbar.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar.tsx similarity index 77% rename from x-pack/plugins/infra/public/components/inventory/toolbars/toolbar.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar.tsx index 63ab6d2f4465a4..3ac9c2c1896286 100644 --- a/x-pack/plugins/infra/public/components/inventory/toolbars/toolbar.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar.tsx @@ -10,15 +10,15 @@ import { SnapshotMetricInput, SnapshotGroupBy, SnapshotCustomMetricInput, -} from '../../../../common/http_api/snapshot_api'; -import { InventoryCloudAccount } from '../../../../common/http_api/inventory_meta_api'; -import { findToolbar } from '../../../../common/inventory_models/toolbars'; +} from '../../../../../../common/http_api/snapshot_api'; +import { InventoryCloudAccount } from '../../../../../../common/http_api/inventory_meta_api'; +import { findToolbar } from '../../../../../../common/inventory_models/toolbars'; import { ToolbarWrapper } from './toolbar_wrapper'; -import { InfraGroupByOptions } from '../../../lib/lib'; -import { IIndexPattern } from '../../../../../../../src/plugins/data/public'; -import { InventoryItemType } from '../../../../common/inventory_models/types'; -import { WaffleOptionsState } from '../../../pages/inventory_view/hooks/use_waffle_options'; +import { InfraGroupByOptions } from '../../../../../lib/lib'; +import { IIndexPattern } from '../../../../../../../../../src/plugins/data/public'; +import { InventoryItemType } from '../../../../../../common/inventory_models/types'; +import { WaffleOptionsState } from '../../hooks/use_waffle_options'; import { SavedViews } from './save_views'; export interface ToolbarProps diff --git a/x-pack/plugins/infra/public/components/inventory/toolbars/toolbar_wrapper.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar_wrapper.tsx similarity index 95% rename from x-pack/plugins/infra/public/components/inventory/toolbars/toolbar_wrapper.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar_wrapper.tsx index fefda94372cfb4..86cc0d8ee62e00 100644 --- a/x-pack/plugins/infra/public/components/inventory/toolbars/toolbar_wrapper.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar_wrapper.tsx @@ -7,12 +7,12 @@ import React from 'react'; import { EuiFlexGroup } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { SnapshotMetricType } from '../../../../common/inventory_models/types'; -import { Toolbar } from '../../eui/toolbar'; +import { SnapshotMetricType } from '../../../../../../common/inventory_models/types'; +import { Toolbar } from '../../../../../components/eui/toolbar'; import { ToolbarProps } from './toolbar'; -import { fieldToName } from '../../waffle/lib/field_to_display_name'; -import { useSourceContext } from '../../../containers/source'; -import { useWaffleOptionsContext } from '../../../pages/inventory_view/hooks/use_waffle_options'; +import { fieldToName } from '../../lib/field_to_display_name'; +import { useSourceContext } from '../../../../../containers/source'; +import { useWaffleOptionsContext } from '../../hooks/use_waffle_options'; interface Props { children: (props: Omit) => React.ReactElement; diff --git a/x-pack/plugins/infra/public/components/waffle/conditional_tooltip.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/conditional_tooltip.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/waffle/conditional_tooltip.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/conditional_tooltip.tsx diff --git a/x-pack/plugins/infra/public/components/waffle/custom_field_panel.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/custom_field_panel.tsx similarity index 97% rename from x-pack/plugins/infra/public/components/waffle/custom_field_panel.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/custom_field_panel.tsx index d2dc535f6d6b32..090d53f1ff7379 100644 --- a/x-pack/plugins/infra/public/components/waffle/custom_field_panel.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/custom_field_panel.tsx @@ -8,7 +8,7 @@ import { EuiButton, EuiComboBox, EuiForm, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; import { IFieldType } from 'src/plugins/data/public'; -import { InfraGroupByOptions } from '../../lib/lib'; +import { InfraGroupByOptions } from '../../../../../lib/lib'; interface Props { onSubmit: (field: string) => void; diff --git a/x-pack/plugins/infra/public/components/waffle/gradient_legend.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/gradient_legend.tsx similarity index 96% rename from x-pack/plugins/infra/public/components/waffle/gradient_legend.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/gradient_legend.tsx index 6b0c4bb41dc980..87f7e4cbff11e6 100644 --- a/x-pack/plugins/infra/public/components/waffle/gradient_legend.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/gradient_legend.tsx @@ -6,13 +6,13 @@ import React from 'react'; -import { euiStyled } from '../../../../observability/public'; +import { euiStyled } from '../../../../../../../observability/public'; import { InfraFormatter, InfraWaffleMapBounds, InfraWaffleMapGradientLegend, InfraWaffleMapGradientRule, -} from '../../lib/lib'; +} from '../../../../../lib/lib'; interface Props { legend: InfraWaffleMapGradientLegend; diff --git a/x-pack/plugins/infra/public/components/waffle/group_name.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/group_name.tsx similarity index 96% rename from x-pack/plugins/infra/public/components/waffle/group_name.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/group_name.tsx index 01bd3600a1624e..308460203b132e 100644 --- a/x-pack/plugins/infra/public/components/waffle/group_name.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/group_name.tsx @@ -6,8 +6,8 @@ import { EuiLink, EuiToolTip } from '@elastic/eui'; import React from 'react'; -import { euiStyled } from '../../../../observability/public'; -import { InfraWaffleMapGroup, InfraWaffleMapOptions } from '../../lib/lib'; +import { euiStyled } from '../../../../../../../observability/public'; +import { InfraWaffleMapGroup, InfraWaffleMapOptions } from '../../../../../lib/lib'; interface Props { onDrilldown: (filter: string) => void; diff --git a/x-pack/plugins/infra/public/components/waffle/group_of_groups.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/group_of_groups.tsx similarity index 90% rename from x-pack/plugins/infra/public/components/waffle/group_of_groups.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/group_of_groups.tsx index 9634293587d49b..6b3f22007f580c 100644 --- a/x-pack/plugins/infra/public/components/waffle/group_of_groups.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/group_of_groups.tsx @@ -6,15 +6,15 @@ import React from 'react'; -import { euiStyled } from '../../../../observability/public'; +import { euiStyled } from '../../../../../../../observability/public'; import { InfraWaffleMapBounds, InfraWaffleMapGroupOfGroups, InfraWaffleMapOptions, -} from '../../lib/lib'; +} from '../../../../../lib/lib'; import { GroupName } from './group_name'; import { GroupOfNodes } from './group_of_nodes'; -import { InventoryItemType } from '../../../common/inventory_models/types'; +import { InventoryItemType } from '../../../../../../common/inventory_models/types'; interface Props { onDrilldown: (filter: string) => void; diff --git a/x-pack/plugins/infra/public/components/waffle/group_of_nodes.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/group_of_nodes.tsx similarity index 90% rename from x-pack/plugins/infra/public/components/waffle/group_of_nodes.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/group_of_nodes.tsx index 6b82671617df7a..fc438ed4ca0a2e 100644 --- a/x-pack/plugins/infra/public/components/waffle/group_of_nodes.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/group_of_nodes.tsx @@ -6,15 +6,15 @@ import React from 'react'; -import { euiStyled } from '../../../../observability/public'; +import { euiStyled } from '../../../../../../../observability/public'; import { InfraWaffleMapBounds, InfraWaffleMapGroupOfNodes, InfraWaffleMapOptions, -} from '../../lib/lib'; +} from '../../../../../lib/lib'; import { GroupName } from './group_name'; import { Node } from './node'; -import { InventoryItemType } from '../../../common/inventory_models/types'; +import { InventoryItemType } from '../../../../../../common/inventory_models/types'; interface Props { onDrilldown: (filter: string) => void; diff --git a/x-pack/plugins/infra/public/components/waffle/legend.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/legend.tsx similarity index 88% rename from x-pack/plugins/infra/public/components/waffle/legend.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/legend.tsx index 13e533b225d4df..ccb4cc71924f42 100644 --- a/x-pack/plugins/infra/public/components/waffle/legend.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/legend.tsx @@ -5,13 +5,13 @@ */ import React from 'react'; -import { euiStyled } from '../../../../observability/public'; -import { InfraFormatter, InfraWaffleMapBounds, InfraWaffleMapLegend } from '../../lib/lib'; +import { euiStyled } from '../../../../../../../observability/public'; +import { InfraFormatter, InfraWaffleMapBounds, InfraWaffleMapLegend } from '../../../../../lib/lib'; import { GradientLegend } from './gradient_legend'; import { LegendControls } from './legend_controls'; -import { isInfraWaffleMapGradientLegend, isInfraWaffleMapStepLegend } from './lib/type_guards'; +import { isInfraWaffleMapGradientLegend, isInfraWaffleMapStepLegend } from '../../lib/type_guards'; import { StepLegend } from './steps_legend'; -import { useWaffleOptionsContext } from '../../pages/inventory_view/hooks/use_waffle_options'; +import { useWaffleOptionsContext } from '../../hooks/use_waffle_options'; interface Props { legend: InfraWaffleMapLegend; bounds: InfraWaffleMapBounds; diff --git a/x-pack/plugins/infra/public/components/waffle/legend_controls.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/legend_controls.tsx similarity index 97% rename from x-pack/plugins/infra/public/components/waffle/legend_controls.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/legend_controls.tsx index 26b5b1c0af727d..6ec21ad2e1b49b 100644 --- a/x-pack/plugins/infra/public/components/waffle/legend_controls.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/legend_controls.tsx @@ -23,8 +23,8 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import React, { SyntheticEvent, useState } from 'react'; -import { euiStyled } from '../../../../observability/public'; -import { InfraWaffleMapBounds } from '../../lib/lib'; +import { euiStyled } from '../../../../../../../observability/public'; +import { InfraWaffleMapBounds } from '../../../../../lib/lib'; interface Props { onChange: (options: { auto: boolean; bounds: InfraWaffleMapBounds }) => void; diff --git a/x-pack/plugins/infra/public/components/waffle/map.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/map.tsx similarity index 84% rename from x-pack/plugins/infra/public/components/waffle/map.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/map.tsx index 7cab2307dacfa1..e34c63d332fd87 100644 --- a/x-pack/plugins/infra/public/components/waffle/map.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/map.tsx @@ -5,20 +5,17 @@ */ import React from 'react'; -import { euiStyled } from '../../../../observability/public'; -import { nodesToWaffleMap } from '../../containers/waffle/nodes_to_wafflemap'; -import { - isWaffleMapGroupWithGroups, - isWaffleMapGroupWithNodes, -} from '../../containers/waffle/type_guards'; -import { InfraWaffleMapBounds, InfraWaffleMapOptions } from '../../lib/lib'; -import { AutoSizer } from '../auto_sizer'; +import { euiStyled } from '../../../../../../../observability/public'; +import { nodesToWaffleMap } from '../../lib/nodes_to_wafflemap'; +import { isWaffleMapGroupWithGroups, isWaffleMapGroupWithNodes } from '../../lib/type_guards'; +import { InfraWaffleMapBounds, InfraWaffleMapOptions } from '../../../../../lib/lib'; +import { AutoSizer } from '../../../../../components/auto_sizer'; import { GroupOfGroups } from './group_of_groups'; import { GroupOfNodes } from './group_of_nodes'; import { Legend } from './legend'; -import { applyWaffleMapLayout } from './lib/apply_wafflemap_layout'; -import { SnapshotNode } from '../../../common/http_api/snapshot_api'; -import { InventoryItemType } from '../../../common/inventory_models/types'; +import { applyWaffleMapLayout } from '../../lib/apply_wafflemap_layout'; +import { SnapshotNode } from '../../../../../../common/http_api/snapshot_api'; +import { InventoryItemType } from '../../../../../../common/inventory_models/types'; interface Props { nodes: SnapshotNode[]; diff --git a/x-pack/plugins/infra/public/components/waffle/metric_control/custom_metric_form.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx similarity index 97% rename from x-pack/plugins/infra/public/components/waffle/metric_control/custom_metric_form.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx index 26e42061ed10bd..aec624c0aff1f5 100644 --- a/x-pack/plugins/infra/public/components/waffle/metric_control/custom_metric_form.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx @@ -26,8 +26,11 @@ import { SnapshotCustomMetricInput, SNAPSHOT_CUSTOM_AGGREGATIONS, SnapshotCustomAggregationRT, -} from '../../../../common/http_api/snapshot_api'; -import { EuiTheme, withTheme } from '../../../../../../legacy/common/eui_styled_components'; +} from '../../../../../../../common/http_api/snapshot_api'; +import { + EuiTheme, + withTheme, +} from '../../../../../../../../../legacy/common/eui_styled_components'; interface SelectedOption { label: string; diff --git a/x-pack/plugins/infra/public/components/waffle/metric_control/get_custom_metric_label.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/get_custom_metric_label.ts similarity index 91% rename from x-pack/plugins/infra/public/components/waffle/metric_control/get_custom_metric_label.ts rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/get_custom_metric_label.ts index 4f88c1b29c1f25..495cc8197d2e78 100644 --- a/x-pack/plugins/infra/public/components/waffle/metric_control/get_custom_metric_label.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/get_custom_metric_label.ts @@ -5,7 +5,7 @@ */ import { i18n } from '@kbn/i18n'; -import { SnapshotCustomMetricInput } from '../../../../common/http_api/snapshot_api'; +import { SnapshotCustomMetricInput } from '../../../../../../../common/http_api/snapshot_api'; export const getCustomMetricLabel = (metric: SnapshotCustomMetricInput) => { const METRIC_LABELS = { diff --git a/x-pack/plugins/infra/public/components/waffle/metric_control/index.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/index.tsx similarity index 97% rename from x-pack/plugins/infra/public/components/waffle/metric_control/index.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/index.tsx index 0f2034fe9cb258..08d5b3e9e06706 100644 --- a/x-pack/plugins/infra/public/components/waffle/metric_control/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/index.tsx @@ -13,14 +13,14 @@ import { SnapshotMetricInput, SnapshotCustomMetricInput, SnapshotCustomMetricInputRT, -} from '../../../../common/http_api/snapshot_api'; +} from '../../../../../../../common/http_api/snapshot_api'; import { CustomMetricForm } from './custom_metric_form'; import { getCustomMetricLabel } from './get_custom_metric_label'; import { MetricsContextMenu } from './metrics_context_menu'; import { ModeSwitcher } from './mode_switcher'; import { MetricsEditMode } from './metrics_edit_mode'; import { CustomMetricMode } from './types'; -import { SnapshotMetricType } from '../../../../common/inventory_models/types'; +import { SnapshotMetricType } from '../../../../../../../common/inventory_models/types'; interface Props { options: Array<{ text: string; value: string }>; diff --git a/x-pack/plugins/infra/public/components/waffle/metric_control/metrics_context_menu.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_context_menu.tsx similarity index 94% rename from x-pack/plugins/infra/public/components/waffle/metric_control/metrics_context_menu.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_context_menu.tsx index 1aacf54244c375..1cdef493aee4f2 100644 --- a/x-pack/plugins/infra/public/components/waffle/metric_control/metrics_context_menu.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_context_menu.tsx @@ -9,11 +9,11 @@ import { SnapshotMetricInput, SnapshotCustomMetricInput, SnapshotCustomMetricInputRT, -} from '../../../../common/http_api/snapshot_api'; +} from '../../../../../../../common/http_api/snapshot_api'; import { SnapshotMetricTypeRT, SnapshotMetricType, -} from '../../../../common/inventory_models/types'; +} from '../../../../../../../common/inventory_models/types'; import { getCustomMetricLabel } from './get_custom_metric_label'; interface Props { diff --git a/x-pack/plugins/infra/public/components/waffle/metric_control/metrics_edit_mode.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_edit_mode.tsx similarity index 92% rename from x-pack/plugins/infra/public/components/waffle/metric_control/metrics_edit_mode.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_edit_mode.tsx index ba1f46815db20c..4d1bc906de0b92 100644 --- a/x-pack/plugins/infra/public/components/waffle/metric_control/metrics_edit_mode.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_edit_mode.tsx @@ -6,9 +6,12 @@ import React from 'react'; import { EuiFlexItem, EuiFlexGroup, EuiButtonIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { SnapshotCustomMetricInput } from '../../../../common/http_api/snapshot_api'; +import { SnapshotCustomMetricInput } from '../../../../../../../common/http_api/snapshot_api'; import { getCustomMetricLabel } from './get_custom_metric_label'; -import { EuiTheme, withTheme } from '../../../../../../legacy/common/eui_styled_components'; +import { + EuiTheme, + withTheme, +} from '../../../../../../../../../legacy/common/eui_styled_components'; interface Props { theme: EuiTheme; diff --git a/x-pack/plugins/infra/public/components/waffle/metric_control/mode_switcher.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/mode_switcher.tsx similarity index 95% rename from x-pack/plugins/infra/public/components/waffle/metric_control/mode_switcher.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/mode_switcher.tsx index 43bb904594c68f..acb740f1750c8d 100644 --- a/x-pack/plugins/infra/public/components/waffle/metric_control/mode_switcher.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/mode_switcher.tsx @@ -8,8 +8,11 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { CustomMetricMode } from './types'; -import { SnapshotCustomMetricInput } from '../../../../common/http_api/snapshot_api'; -import { EuiTheme, withTheme } from '../../../../../../legacy/common/eui_styled_components'; +import { SnapshotCustomMetricInput } from '../../../../../../../common/http_api/snapshot_api'; +import { + EuiTheme, + withTheme, +} from '../../../../../../../../../legacy/common/eui_styled_components'; interface Props { theme: EuiTheme; diff --git a/x-pack/plugins/infra/public/components/waffle/metric_control/types.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/types.ts similarity index 100% rename from x-pack/plugins/infra/public/components/waffle/metric_control/types.ts rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/types.ts diff --git a/x-pack/plugins/infra/public/components/waffle/node.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node.tsx similarity index 93% rename from x-pack/plugins/infra/public/components/waffle/node.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node.tsx index 4eb5ccb8c1b4d9..fd5b5b01f329fa 100644 --- a/x-pack/plugins/infra/public/components/waffle/node.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node.tsx @@ -10,11 +10,15 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { ConditionalToolTip } from './conditional_tooltip'; -import { euiStyled } from '../../../../observability/public'; -import { InfraWaffleMapBounds, InfraWaffleMapNode, InfraWaffleMapOptions } from '../../lib/lib'; -import { colorFromValue } from './lib/color_from_value'; +import { euiStyled } from '../../../../../../../observability/public'; +import { + InfraWaffleMapBounds, + InfraWaffleMapNode, + InfraWaffleMapOptions, +} from '../../../../../lib/lib'; +import { colorFromValue } from '../../lib/color_from_value'; import { NodeContextMenu } from './node_context_menu'; -import { InventoryItemType } from '../../../common/inventory_models/types'; +import { InventoryItemType } from '../../../../../../common/inventory_models/types'; const initialState = { isPopoverOpen: false, diff --git a/x-pack/plugins/infra/public/components/waffle/node_context_menu.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node_context_menu.tsx similarity index 91% rename from x-pack/plugins/infra/public/components/waffle/node_context_menu.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node_context_menu.tsx index 5f05cebd8f616a..275635a33ec266 100644 --- a/x-pack/plugins/infra/public/components/waffle/node_context_menu.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node_context_menu.tsx @@ -9,12 +9,13 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import React, { useMemo, useState } from 'react'; -import { InfraWaffleMapNode, InfraWaffleMapOptions } from '../../lib/lib'; -import { getNodeDetailUrl, getNodeLogsUrl } from '../../pages/link_to'; -import { createUptimeLink } from './lib/create_uptime_link'; -import { findInventoryModel, findInventoryFields } from '../../../common/inventory_models'; -import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; -import { InventoryItemType } from '../../../common/inventory_models/types'; +import { AlertFlyout } from '../../../../../components/alerting/metrics/alert_flyout'; +import { InfraWaffleMapNode, InfraWaffleMapOptions } from '../../../../../lib/lib'; +import { getNodeDetailUrl, getNodeLogsUrl } from '../../../../link_to'; +import { createUptimeLink } from '../../lib/create_uptime_link'; +import { findInventoryModel, findInventoryFields } from '../../../../../../common/inventory_models'; +import { useKibana } from '../../../../../../../../../src/plugins/kibana_react/public'; +import { InventoryItemType } from '../../../../../../common/inventory_models/types'; import { Section, SectionLinkProps, @@ -23,9 +24,8 @@ import { SectionSubtitle, SectionLinks, SectionLink, -} from '../../../../observability/public'; -import { useLinkProps } from '../../hooks/use_link_props'; -import { AlertFlyout } from '../alerting/metrics/alert_flyout'; +} from '../../../../../../../observability/public'; +import { useLinkProps } from '../../../../../hooks/use_link_props'; interface Props { options: InfraWaffleMapOptions; diff --git a/x-pack/plugins/infra/public/components/waffle/steps_legend.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/steps_legend.tsx similarity index 95% rename from x-pack/plugins/infra/public/components/waffle/steps_legend.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/steps_legend.tsx index d2079d53dad71b..1ef0f2d0c42889 100644 --- a/x-pack/plugins/infra/public/components/waffle/steps_legend.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/steps_legend.tsx @@ -7,13 +7,13 @@ import { darken } from 'polished'; import React from 'react'; -import { euiStyled } from '../../../../observability/public'; +import { euiStyled } from '../../../../../../../observability/public'; import { InfraFormatter, InfraWaffleMapRuleOperator, InfraWaffleMapStepLegend, InfraWaffleMapStepRule, -} from '../../lib/lib'; +} from '../../../../../lib/lib'; const OPERATORS = { [InfraWaffleMapRuleOperator.gte]: '>=', diff --git a/x-pack/plugins/infra/public/components/waffle/view_switcher.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/view_switcher.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/waffle/view_switcher.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/view_switcher.tsx diff --git a/x-pack/plugins/infra/public/components/waffle/waffle_accounts_controls.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_accounts_controls.tsx similarity index 94% rename from x-pack/plugins/infra/public/components/waffle/waffle_accounts_controls.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_accounts_controls.tsx index 56c3a205b05d48..a8b0cf21bce85e 100644 --- a/x-pack/plugins/infra/public/components/waffle/waffle_accounts_controls.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_accounts_controls.tsx @@ -14,7 +14,7 @@ import { import React, { useCallback, useState, useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { InventoryCloudAccount } from '../../../common/http_api/inventory_meta_api'; +import { InventoryCloudAccount } from '../../../../../../common/http_api/inventory_meta_api'; interface Props { accountId: string; @@ -24,7 +24,7 @@ interface Props { export const WaffleAccountsControls = (props: Props) => { const { accountId, options } = props; - const [isOpen, setIsOpen] = useState(); + const [isOpen, setIsOpen] = useState(false); const showPopover = useCallback(() => { setIsOpen(true); diff --git a/x-pack/plugins/infra/public/components/waffle/waffle_group_by_controls.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_group_by_controls.tsx similarity index 95% rename from x-pack/plugins/infra/public/components/waffle/waffle_group_by_controls.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_group_by_controls.tsx index 1a3cef591bc077..bc763d2cf93785 100644 --- a/x-pack/plugins/infra/public/components/waffle/waffle_group_by_controls.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_group_by_controls.tsx @@ -17,11 +17,11 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import React from 'react'; import { IFieldType } from 'src/plugins/data/public'; -import { InfraGroupByOptions } from '../../lib/lib'; +import { InfraGroupByOptions } from '../../../../../lib/lib'; import { CustomFieldPanel } from './custom_field_panel'; -import { euiStyled } from '../../../../observability/public'; -import { InventoryItemType } from '../../../common/inventory_models/types'; -import { SnapshotGroupBy } from '../../../common/http_api/snapshot_api'; +import { euiStyled } from '../../../../../../../observability/public'; +import { InventoryItemType } from '../../../../../../common/inventory_models/types'; +import { SnapshotGroupBy } from '../../../../../../common/http_api/snapshot_api'; interface Props { options: Array<{ text: string; field: string; toolTipContent?: string }>; diff --git a/x-pack/plugins/infra/public/components/waffle/waffle_inventory_switcher.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_inventory_switcher.tsx similarity index 94% rename from x-pack/plugins/infra/public/components/waffle/waffle_inventory_switcher.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_inventory_switcher.tsx index 21da10a0a76502..23e06823f407f4 100644 --- a/x-pack/plugins/infra/public/components/waffle/waffle_inventory_switcher.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_inventory_switcher.tsx @@ -14,9 +14,9 @@ import { import React, { useCallback, useState, useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { findInventoryModel } from '../../../common/inventory_models'; -import { InventoryItemType } from '../../../common/inventory_models/types'; -import { useWaffleOptionsContext } from '../../pages/inventory_view/hooks/use_waffle_options'; +import { findInventoryModel } from '../../../../../../common/inventory_models'; +import { InventoryItemType } from '../../../../../../common/inventory_models/types'; +import { useWaffleOptionsContext } from '../../hooks/use_waffle_options'; const getDisplayNameForType = (type: InventoryItemType) => { const inventoryModel = findInventoryModel(type); diff --git a/x-pack/plugins/infra/public/components/waffle/waffle_region_controls.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_region_controls.tsx similarity index 97% rename from x-pack/plugins/infra/public/components/waffle/waffle_region_controls.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_region_controls.tsx index 52377bf4b8296e..671e44f42ef6a5 100644 --- a/x-pack/plugins/infra/public/components/waffle/waffle_region_controls.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_region_controls.tsx @@ -23,7 +23,7 @@ interface Props { export const WaffleRegionControls = (props: Props) => { const { region, options } = props; - const [isOpen, setIsOpen] = useState(); + const [isOpen, setIsOpen] = useState(false); const showPopover = useCallback(() => { setIsOpen(true); diff --git a/x-pack/plugins/infra/public/components/waffle/waffle_time_controls.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_time_controls.tsx similarity index 95% rename from x-pack/plugins/infra/public/components/waffle/waffle_time_controls.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_time_controls.tsx index 458bb674afadef..7f190f21484d93 100644 --- a/x-pack/plugins/infra/public/components/waffle/waffle_time_controls.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_time_controls.tsx @@ -8,7 +8,7 @@ import { EuiButtonEmpty, EuiDatePicker, EuiFormControlLayout } from '@elastic/eu import { FormattedMessage } from '@kbn/i18n/react'; import moment, { Moment } from 'moment'; import React, { useCallback } from 'react'; -import { useWaffleTimeContext } from '../../pages/inventory_view/hooks/use_waffle_time'; +import { useWaffleTimeContext } from '../../hooks/use_waffle_time'; export const WaffleTimeControls = () => { const { diff --git a/x-pack/plugins/infra/public/containers/inventory_metadata/use_inventory_meta.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_inventory_meta.ts similarity index 79% rename from x-pack/plugins/infra/public/containers/inventory_metadata/use_inventory_meta.ts rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_inventory_meta.ts index 0ed1f3e35449b4..b038491690a137 100644 --- a/x-pack/plugins/infra/public/containers/inventory_metadata/use_inventory_meta.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_inventory_meta.ts @@ -7,13 +7,13 @@ import { fold } from 'fp-ts/lib/Either'; import { identity } from 'fp-ts/lib/function'; import { pipe } from 'fp-ts/lib/pipeable'; import { useEffect } from 'react'; -import { throwErrors, createPlainError } from '../../../common/runtime_types'; -import { useHTTPRequest } from '../../hooks/use_http_request'; +import { throwErrors, createPlainError } from '../../../../../common/runtime_types'; +import { useHTTPRequest } from '../../../../hooks/use_http_request'; import { InventoryMetaResponseRT, InventoryMetaResponse, -} from '../../../common/http_api/inventory_meta_api'; -import { InventoryItemType } from '../../../common/inventory_models/types'; +} from '../../../../../common/http_api/inventory_meta_api'; +import { InventoryItemType } from '../../../../../common/inventory_models/types'; export function useInventoryMeta(sourceId: string, nodeType: InventoryItemType) { const decodeResponse = (response: any) => { diff --git a/x-pack/plugins/infra/public/containers/waffle/use_snaphot.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_snaphot.ts similarity index 83% rename from x-pack/plugins/infra/public/containers/waffle/use_snaphot.ts rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_snaphot.ts index 31f02f46caedac..3ec63d7b2de286 100644 --- a/x-pack/plugins/infra/public/containers/waffle/use_snaphot.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_snaphot.ts @@ -8,14 +8,17 @@ import { useEffect } from 'react'; import { fold } from 'fp-ts/lib/Either'; import { identity } from 'fp-ts/lib/function'; import { pipe } from 'fp-ts/lib/pipeable'; -import { throwErrors, createPlainError } from '../../../common/runtime_types'; -import { useHTTPRequest } from '../../hooks/use_http_request'; +import { throwErrors, createPlainError } from '../../../../../common/runtime_types'; +import { useHTTPRequest } from '../../../../hooks/use_http_request'; import { SnapshotNodeResponseRT, SnapshotNodeResponse, SnapshotGroupBy, -} from '../../../common/http_api/snapshot_api'; -import { InventoryItemType, SnapshotMetricType } from '../../../common/inventory_models/types'; +} from '../../../../../common/http_api/snapshot_api'; +import { + InventoryItemType, + SnapshotMetricType, +} from '../../../../../common/inventory_models/types'; export function useSnapshot( filterQuery: string | null | undefined, diff --git a/x-pack/plugins/infra/public/pages/inventory_view/hooks/use_waffle_filters.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_filters.ts similarity index 90% rename from x-pack/plugins/infra/public/pages/inventory_view/hooks/use_waffle_filters.ts rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_filters.ts index 02c079dcaddc40..f6cbb59779039a 100644 --- a/x-pack/plugins/infra/public/pages/inventory_view/hooks/use_waffle_filters.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_filters.ts @@ -10,10 +10,10 @@ import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; import createContainter from 'constate'; -import { useUrlState } from '../../../utils/use_url_state'; -import { useSourceContext } from '../../../containers/source'; -import { convertKueryToElasticSearchQuery } from '../../../utils/kuery'; -import { esKuery } from '../../../../../../../src/plugins/data/public'; +import { useUrlState } from '../../../../utils/use_url_state'; +import { useSourceContext } from '../../../../containers/source'; +import { convertKueryToElasticSearchQuery } from '../../../../utils/kuery'; +import { esKuery } from '../../../../../../../../src/plugins/data/public'; const validateKuery = (expression: string) => { try { diff --git a/x-pack/plugins/infra/public/pages/inventory_view/hooks/use_waffle_options.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts similarity index 95% rename from x-pack/plugins/infra/public/pages/inventory_view/hooks/use_waffle_options.ts rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts index 2853917d5f6838..32bfe6e085b4e4 100644 --- a/x-pack/plugins/infra/public/pages/inventory_view/hooks/use_waffle_options.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts @@ -17,9 +17,9 @@ import { SnapshotMetricInputRT, SnapshotGroupByRT, SnapshotCustomMetricInputRT, -} from '../../../../common/http_api/snapshot_api'; -import { useUrlState } from '../../../utils/use_url_state'; -import { InventoryItemType, ItemTypeRT } from '../../../../common/inventory_models/types'; +} from '../../../../../common/http_api/snapshot_api'; +import { useUrlState } from '../../../../utils/use_url_state'; +import { InventoryItemType, ItemTypeRT } from '../../../../../common/inventory_models/types'; export const DEFAULT_WAFFLE_OPTIONS_STATE: WaffleOptionsState = { metric: { type: 'cpu' }, diff --git a/x-pack/plugins/infra/public/pages/inventory_view/hooks/use_waffle_time.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_time.ts similarity index 97% rename from x-pack/plugins/infra/public/pages/inventory_view/hooks/use_waffle_time.ts rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_time.ts index 051b5e598cb757..db3abd37b58dd8 100644 --- a/x-pack/plugins/infra/public/pages/inventory_view/hooks/use_waffle_time.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_time.ts @@ -9,7 +9,7 @@ import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; import createContainer from 'constate'; -import { useUrlState } from '../../../utils/use_url_state'; +import { useUrlState } from '../../../../utils/use_url_state'; export const DEFAULT_WAFFLE_TIME_STATE: WaffleTimeState = { currentTime: Date.now(), diff --git a/x-pack/plugins/infra/public/pages/inventory_view/hooks/use_waffle_view_state.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_view_state.ts similarity index 100% rename from x-pack/plugins/infra/public/pages/inventory_view/hooks/use_waffle_view_state.ts rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_view_state.ts diff --git a/x-pack/plugins/infra/public/pages/infrastructure/snapshot/index.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/index.tsx similarity index 98% rename from x-pack/plugins/infra/public/pages/infrastructure/snapshot/index.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/index.tsx index 48cc56388c0f24..e473aea7a1f0bc 100644 --- a/x-pack/plugins/infra/public/pages/infrastructure/snapshot/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/index.tsx @@ -20,7 +20,7 @@ import { ViewSourceConfigurationButton } from '../../../components/source_config import { Source } from '../../../containers/source'; import { useTrackPageview } from '../../../../../observability/public'; import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; -import { Layout } from '../../../components/inventory/layout'; +import { Layout } from './components/layout'; import { useLinkProps } from '../../../hooks/use_link_props'; export const SnapshotPage = () => { diff --git a/x-pack/plugins/infra/public/components/waffle/lib/apply_wafflemap_layout.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/apply_wafflemap_layout.ts similarity index 94% rename from x-pack/plugins/infra/public/components/waffle/lib/apply_wafflemap_layout.ts rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/apply_wafflemap_layout.ts index 5f3c06fcfbba77..68600ac5d2ce49 100644 --- a/x-pack/plugins/infra/public/components/waffle/lib/apply_wafflemap_layout.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/apply_wafflemap_layout.ts @@ -4,11 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ import { first, sortBy } from 'lodash'; -import { - isWaffleMapGroupWithGroups, - isWaffleMapGroupWithNodes, -} from '../../../containers/waffle/type_guards'; -import { InfraWaffleMapGroup } from '../../../lib/lib'; +import { isWaffleMapGroupWithGroups, isWaffleMapGroupWithNodes } from './type_guards'; +import { InfraWaffleMapGroup } from '../../../../lib/lib'; import { sizeOfSquares } from './size_of_squares'; export function getColumns(n: number, w = 1, h = 1) { diff --git a/x-pack/plugins/infra/public/components/waffle/lib/color_from_value.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/color_from_value.ts similarity index 98% rename from x-pack/plugins/infra/public/components/waffle/lib/color_from_value.ts rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/color_from_value.ts index c082686bb9d63a..334865306ee88e 100644 --- a/x-pack/plugins/infra/public/components/waffle/lib/color_from_value.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/color_from_value.ts @@ -12,7 +12,7 @@ import { InfraWaffleMapLegend, InfraWaffleMapRuleOperator, InfraWaffleMapStepLegend, -} from '../../../lib/lib'; +} from '../../../../lib/lib'; import { isInfraWaffleMapGradientLegend, isInfraWaffleMapStepLegend } from './type_guards'; const OPERATOR_TO_FN = { diff --git a/x-pack/plugins/infra/public/components/waffle/lib/create_uptime_link.test.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_uptime_link.test.ts similarity index 96% rename from x-pack/plugins/infra/public/components/waffle/lib/create_uptime_link.test.ts rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_uptime_link.test.ts index 902969c83ba393..5f760cf2f591e2 100644 --- a/x-pack/plugins/infra/public/components/waffle/lib/create_uptime_link.test.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_uptime_link.test.ts @@ -5,8 +5,8 @@ */ import { createUptimeLink } from './create_uptime_link'; -import { InfraWaffleMapOptions, InfraFormatterType } from '../../../lib/lib'; -import { SnapshotMetricType } from '../../../../common/inventory_models/types'; +import { InfraWaffleMapOptions, InfraFormatterType } from '../../../../lib/lib'; +import { SnapshotMetricType } from '../../../../../common/inventory_models/types'; const options: InfraWaffleMapOptions = { fields: { diff --git a/x-pack/plugins/infra/public/components/waffle/lib/create_uptime_link.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_uptime_link.ts similarity index 83% rename from x-pack/plugins/infra/public/components/waffle/lib/create_uptime_link.ts rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_uptime_link.ts index 72b46f4fb5c7b7..6c089ee8d22f46 100644 --- a/x-pack/plugins/infra/public/components/waffle/lib/create_uptime_link.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_uptime_link.ts @@ -5,9 +5,9 @@ */ import { get } from 'lodash'; -import { InfraWaffleMapNode, InfraWaffleMapOptions } from '../../../lib/lib'; -import { InventoryItemType } from '../../../../common/inventory_models/types'; -import { LinkDescriptor } from '../../../hooks/use_link_props'; +import { InfraWaffleMapNode, InfraWaffleMapOptions } from '../../../../lib/lib'; +import { InventoryItemType } from '../../../../../common/inventory_models/types'; +import { LinkDescriptor } from '../../../../hooks/use_link_props'; export const createUptimeLink = ( options: InfraWaffleMapOptions, diff --git a/x-pack/plugins/infra/public/components/waffle/lib/field_to_display_name.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/field_to_display_name.ts similarity index 100% rename from x-pack/plugins/infra/public/components/waffle/lib/field_to_display_name.ts rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/field_to_display_name.ts diff --git a/x-pack/plugins/infra/public/containers/waffle/nodes_to_wafflemap.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/nodes_to_wafflemap.ts similarity index 97% rename from x-pack/plugins/infra/public/containers/waffle/nodes_to_wafflemap.ts rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/nodes_to_wafflemap.ts index d2511ba7e669e6..469b54b2d9d684 100644 --- a/x-pack/plugins/infra/public/containers/waffle/nodes_to_wafflemap.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/nodes_to_wafflemap.ts @@ -11,9 +11,9 @@ import { InfraWaffleMapGroupOfGroups, InfraWaffleMapGroupOfNodes, InfraWaffleMapNode, -} from '../../lib/lib'; +} from '../../../../lib/lib'; import { isWaffleMapGroupWithGroups, isWaffleMapGroupWithNodes } from './type_guards'; -import { SnapshotNodePath, SnapshotNode } from '../../../common/http_api/snapshot_api'; +import { SnapshotNodePath, SnapshotNode } from '../../../../../common/http_api/snapshot_api'; export function createId(path: SnapshotNodePath[]) { return path.map(p => p.value).join('/'); diff --git a/x-pack/plugins/infra/public/components/waffle/lib/size_of_squares.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/size_of_squares.ts similarity index 100% rename from x-pack/plugins/infra/public/components/waffle/lib/size_of_squares.ts rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/size_of_squares.ts diff --git a/x-pack/plugins/infra/public/containers/waffle/type_guards.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/type_guards.ts similarity index 55% rename from x-pack/plugins/infra/public/containers/waffle/type_guards.ts rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/type_guards.ts index 3e21e3a56a6c6a..62d02022d4c939 100644 --- a/x-pack/plugins/infra/public/containers/waffle/type_guards.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/type_guards.ts @@ -4,7 +4,22 @@ * you may not use this file except in compliance with the Elastic License. */ -import { InfraWaffleMapGroupOfGroups, InfraWaffleMapGroupOfNodes } from '../../lib/lib'; +import { + InfraWaffleMapGroupOfGroups, + InfraWaffleMapGroupOfNodes, + InfraWaffleMapGradientLegend, + InfraWaffleMapStepLegend, +} from '../../../../lib/lib'; + +export function isInfraWaffleMapStepLegend(subject: any): subject is InfraWaffleMapStepLegend { + return subject.type && subject.type === 'step'; +} + +export function isInfraWaffleMapGradientLegend( + subject: any +): subject is InfraWaffleMapGradientLegend { + return subject.type && subject.type === 'gradient'; +} export function isWaffleMapGroupWithNodes(subject: any): subject is InfraWaffleMapGroupOfNodes { return subject && subject.nodes != null && Array.isArray(subject.nodes); diff --git a/x-pack/plugins/infra/public/pages/infrastructure/snapshot/toolbar.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/toolbar.tsx similarity index 75% rename from x-pack/plugins/infra/public/pages/infrastructure/snapshot/toolbar.tsx rename to x-pack/plugins/infra/public/pages/metrics/inventory_view/toolbar.tsx index ccdaa5e8dc7857..d6a87a0197f5f7 100644 --- a/x-pack/plugins/infra/public/pages/infrastructure/snapshot/toolbar.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/toolbar.tsx @@ -8,9 +8,9 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import React from 'react'; import { Toolbar } from '../../../components/eui/toolbar'; -import { WaffleTimeControls } from '../../../components/waffle/waffle_time_controls'; -import { WaffleInventorySwitcher } from '../../../components/waffle/waffle_inventory_switcher'; -import { SearchBar } from '../../inventory_view/compontents/search_bar'; +import { WaffleTimeControls } from './components/waffle/waffle_time_controls'; +import { WaffleInventorySwitcher } from './components/waffle/waffle_inventory_switcher'; +import { SearchBar } from './components/search_bar'; export const SnapshotToolbar = () => ( diff --git a/x-pack/plugins/infra/public/pages/metrics/components/chart_section_vis.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/chart_section_vis.tsx similarity index 94% rename from x-pack/plugins/infra/public/pages/metrics/components/chart_section_vis.tsx rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/components/chart_section_vis.tsx index 290f0eda452ce2..588a0d84918c6c 100644 --- a/x-pack/plugins/infra/public/pages/metrics/components/chart_section_vis.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/chart_section_vis.tsx @@ -8,7 +8,7 @@ import moment from 'moment'; import { i18n } from '@kbn/i18n'; import { Axis, Chart, niceTimeFormatter, Position, Settings, TooltipValue } from '@elastic/charts'; import { EuiPageContentBody } from '@elastic/eui'; -import { getChartTheme } from '../../../components/metrics_explorer/helpers/get_chart_theme'; +import { getChartTheme } from '../../metrics_explorer/components/helpers/get_chart_theme'; import { SeriesChart } from './series_chart'; import { getFormatter, @@ -19,8 +19,8 @@ import { seriesHasLessThen2DataPoints, } from './helpers'; import { ErrorMessage } from './error_message'; -import { useKibanaUiSetting } from '../../../utils/use_kibana_ui_setting'; -import { useUiSetting } from '../../../../../../../src/plugins/kibana_react/public'; +import { useKibanaUiSetting } from '../../../../utils/use_kibana_ui_setting'; +import { useUiSetting } from '../../../../../../../../src/plugins/kibana_react/public'; import { VisSectionProps } from '../types'; export const ChartSectionVis = ({ diff --git a/x-pack/plugins/infra/public/pages/metrics/components/error_message.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/error_message.tsx similarity index 100% rename from x-pack/plugins/infra/public/pages/metrics/components/error_message.tsx rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/components/error_message.tsx diff --git a/x-pack/plugins/infra/public/pages/metrics/components/gauges_section_vis.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/gauges_section_vis.tsx similarity index 92% rename from x-pack/plugins/infra/public/pages/metrics/components/gauges_section_vis.tsx rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/components/gauges_section_vis.tsx index e069b52be8be70..0aab676b7d6c54 100644 --- a/x-pack/plugins/infra/public/pages/metrics/components/gauges_section_vis.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/gauges_section_vis.tsx @@ -16,9 +16,9 @@ import { import { get, last, max } from 'lodash'; import React, { ReactText } from 'react'; -import { euiStyled } from '../../../../../observability/public'; -import { createFormatter } from '../../../utils/formatters'; -import { InventoryFormatterType } from '../../../../common/inventory_models/types'; +import { euiStyled } from '../../../../../../observability/public'; +import { createFormatter } from '../../../../utils/formatters'; +import { InventoryFormatterType } from '../../../../../common/inventory_models/types'; import { SeriesOverrides, VisSectionProps } from '../types'; import { getChartName } from './helpers'; diff --git a/x-pack/plugins/infra/public/pages/metrics/components/helpers.ts b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/helpers.ts similarity index 91% rename from x-pack/plugins/infra/public/pages/metrics/components/helpers.ts rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/components/helpers.ts index 4449196f2fb537..bb4ad326609520 100644 --- a/x-pack/plugins/infra/public/pages/metrics/components/helpers.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/helpers.ts @@ -7,15 +7,15 @@ import { ReactText } from 'react'; import Color from 'color'; import { get, first, last, min, max } from 'lodash'; -import { createFormatter } from '../../../utils/formatters'; -import { InfraDataSeries } from '../../../graphql/types'; +import { createFormatter } from '../../../../utils/formatters'; +import { InfraDataSeries } from '../../../../graphql/types'; import { InventoryVisTypeRT, InventoryFormatterType, InventoryVisType, -} from '../../../../common/inventory_models/types'; +} from '../../../../../common/inventory_models/types'; import { SeriesOverrides } from '../types'; -import { NodeDetailsMetricData } from '../../../../common/http_api/node_details_api'; +import { NodeDetailsMetricData } from '../../../../../common/http_api/node_details_api'; /** * Returns a formatter diff --git a/x-pack/plugins/infra/public/pages/metrics/components/invalid_node.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/invalid_node.tsx similarity index 90% rename from x-pack/plugins/infra/public/pages/metrics/components/invalid_node.tsx rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/components/invalid_node.tsx index b089e2237c2e57..6d83017a3f6892 100644 --- a/x-pack/plugins/infra/public/pages/metrics/components/invalid_node.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/invalid_node.tsx @@ -7,9 +7,9 @@ import { EuiButton, EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import React from 'react'; -import { euiStyled } from '../../../../../observability/public'; -import { ViewSourceConfigurationButton } from '../../../components/source_configuration'; -import { useLinkProps } from '../../../hooks/use_link_props'; +import { euiStyled } from '../../../../../../observability/public'; +import { ViewSourceConfigurationButton } from '../../../../components/source_configuration'; +import { useLinkProps } from '../../../../hooks/use_link_props'; interface InvalidNodeErrorProps { nodeName: string; diff --git a/x-pack/plugins/infra/public/pages/metrics/components/layout_content.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/layout_content.tsx similarity index 84% rename from x-pack/plugins/infra/public/pages/metrics/components/layout_content.tsx rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/components/layout_content.tsx index 4e10f245acdccc..46201025175492 100644 --- a/x-pack/plugins/infra/public/pages/metrics/components/layout_content.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/layout_content.tsx @@ -5,7 +5,7 @@ */ import { EuiPageContent } from '@elastic/eui'; -import { euiStyled } from '../../../../../observability/public'; +import { euiStyled } from '../../../../../../observability/public'; export const LayoutContent = euiStyled(EuiPageContent)` position: relative; diff --git a/x-pack/plugins/infra/public/pages/metrics/components/metadata_details.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/metadata_details.tsx similarity index 97% rename from x-pack/plugins/infra/public/pages/metrics/components/metadata_details.tsx rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/components/metadata_details.tsx index 3bf492d398f2cf..7ca69dd56251d3 100644 --- a/x-pack/plugins/infra/public/pages/metrics/components/metadata_details.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/metadata_details.tsx @@ -8,8 +8,8 @@ import React, { useContext, useState, useCallback, useMemo } from 'react'; import { EuiButtonIcon, EuiFlexGrid, EuiFlexItem, EuiTitle, EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { get } from 'lodash'; -import { InfraMetadata } from '../../../../common/http_api'; -import { euiStyled } from '../../../../../observability/public'; +import { InfraMetadata } from '../../../../../common/http_api'; +import { euiStyled } from '../../../../../../observability/public'; import { MetadataContext } from '../containers/metadata_context'; interface FieldDef { diff --git a/x-pack/plugins/infra/public/pages/metrics/components/node_details_page.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/node_details_page.tsx similarity index 90% rename from x-pack/plugins/infra/public/pages/metrics/components/node_details_page.tsx rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/components/node_details_page.tsx index dd2a5f2bdb39e6..0d0bc8c82397e8 100644 --- a/x-pack/plugins/infra/public/pages/metrics/components/node_details_page.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/node_details_page.tsx @@ -13,19 +13,19 @@ import { EuiHideFor, EuiTitle, } from '@elastic/eui'; -import { InfraTimerangeInput } from '../../../../common/http_api/snapshot_api'; -import { InventoryMetric, InventoryItemType } from '../../../../common/inventory_models/types'; -import { useNodeDetails } from '../../../containers/node_details/use_node_details'; +import { InfraTimerangeInput } from '../../../../../common/http_api/snapshot_api'; +import { InventoryMetric, InventoryItemType } from '../../../../../common/inventory_models/types'; +import { useNodeDetails } from '../hooks/use_node_details'; import { MetricsSideNav } from './side_nav'; -import { AutoSizer } from '../../../components/auto_sizer'; +import { AutoSizer } from '../../../../components/auto_sizer'; import { MetricsTimeControls } from './time_controls'; import { SideNavContext, NavItem } from '../lib/side_nav_context'; import { PageBody } from './page_body'; -import { euiStyled } from '../../../../../observability/public'; +import { euiStyled } from '../../../../../../observability/public'; import { MetricsTimeInput } from '../hooks/use_metrics_time'; -import { InfraMetadata } from '../../../../common/http_api/metadata_api'; +import { InfraMetadata } from '../../../../../common/http_api/metadata_api'; import { PageError } from './page_error'; -import { MetadataContext } from '../../../pages/metrics/containers/metadata_context'; +import { MetadataContext } from '../containers/metadata_context'; interface Props { name: string; diff --git a/x-pack/plugins/infra/public/pages/metrics/components/page_body.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/page_body.tsx similarity index 82% rename from x-pack/plugins/infra/public/pages/metrics/components/page_body.tsx rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/components/page_body.tsx index e651d6b92d9811..68166a6e53bfda 100644 --- a/x-pack/plugins/infra/public/pages/metrics/components/page_body.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/page_body.tsx @@ -6,13 +6,13 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { findLayout } from '../../../../common/inventory_models/layouts'; -import { InventoryItemType } from '../../../../common/inventory_models/types'; +import { findLayout } from '../../../../../common/inventory_models/layouts'; +import { InventoryItemType } from '../../../../../common/inventory_models/types'; import { MetricsTimeInput } from '../hooks/use_metrics_time'; -import { InfraLoadingPanel } from '../../../components/loading'; -import { NoData } from '../../../components/empty_states'; -import { NodeDetailsMetricData } from '../../../../common/http_api/node_details_api'; +import { InfraLoadingPanel } from '../../../../components/loading'; +import { NoData } from '../../../../components/empty_states'; +import { NodeDetailsMetricData } from '../../../../../common/http_api/node_details_api'; interface Props { loading: boolean; diff --git a/x-pack/plugins/infra/public/pages/metrics/components/page_error.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/page_error.tsx similarity index 90% rename from x-pack/plugins/infra/public/pages/metrics/components/page_error.tsx rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/components/page_error.tsx index e54cdcd151f6fc..bda2a5941e0230 100644 --- a/x-pack/plugins/infra/public/pages/metrics/components/page_error.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/page_error.tsx @@ -10,8 +10,8 @@ import { i18n } from '@kbn/i18n'; import { IHttpFetchError } from 'src/core/public'; import { InvalidNodeError } from './invalid_node'; // import { InfraMetricsErrorCodes } from '../../../../common/errors'; -import { DocumentTitle } from '../../../components/document_title'; -import { ErrorPageBody } from '../../error'; +import { DocumentTitle } from '../../../../components/document_title'; +import { ErrorPageBody } from '../../../error'; interface Props { name: string; diff --git a/x-pack/plugins/infra/public/pages/metrics/components/section.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/section.tsx similarity index 100% rename from x-pack/plugins/infra/public/pages/metrics/components/section.tsx rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/components/section.tsx diff --git a/x-pack/plugins/infra/public/pages/metrics/components/series_chart.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/series_chart.tsx similarity index 93% rename from x-pack/plugins/infra/public/pages/metrics/components/series_chart.tsx rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/components/series_chart.tsx index 849a5b89221650..0d7716ad3cc669 100644 --- a/x-pack/plugins/infra/public/pages/metrics/components/series_chart.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/series_chart.tsx @@ -13,8 +13,8 @@ import { BarSeriesStyle, AreaSeriesStyle, } from '@elastic/charts'; -import { InfraDataSeries } from '../../../graphql/types'; -import { InventoryVisType } from '../../../../common/inventory_models/types'; +import { InfraDataSeries } from '../../../../graphql/types'; +import { InventoryVisType } from '../../../../../common/inventory_models/types'; interface Props { id: string; diff --git a/x-pack/plugins/infra/public/pages/metrics/components/side_nav.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/side_nav.tsx similarity index 95% rename from x-pack/plugins/infra/public/pages/metrics/components/side_nav.tsx rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/components/side_nav.tsx index 94f97c7f45e61f..1cba3366acbbbf 100644 --- a/x-pack/plugins/infra/public/pages/metrics/components/side_nav.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/side_nav.tsx @@ -6,7 +6,7 @@ import { EuiHideFor, EuiPageSideBar, EuiShowFor, EuiSideNav } from '@elastic/eui'; import React, { useState, useCallback } from 'react'; -import { euiStyled } from '../../../../../observability/public'; +import { euiStyled } from '../../../../../../observability/public'; import { NavItem } from '../lib/side_nav_context'; interface Props { diff --git a/x-pack/plugins/infra/public/pages/metrics/components/sub_section.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/sub_section.tsx similarity index 94% rename from x-pack/plugins/infra/public/pages/metrics/components/sub_section.tsx rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/components/sub_section.tsx index 325d5102931354..7b269adc96638b 100644 --- a/x-pack/plugins/infra/public/pages/metrics/components/sub_section.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/sub_section.tsx @@ -6,7 +6,7 @@ import React, { isValidElement, cloneElement, FunctionComponent, Children, useMemo } from 'react'; import { EuiTitle } from '@elastic/eui'; -import { InventoryMetric } from '../../../../common/inventory_models/types'; +import { InventoryMetric } from '../../../../../common/inventory_models/types'; import { LayoutProps } from '../types'; type SubSectionProps = LayoutProps & { diff --git a/x-pack/plugins/infra/public/pages/metrics/components/time_controls.test.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/time_controls.test.tsx similarity index 96% rename from x-pack/plugins/infra/public/pages/metrics/components/time_controls.test.tsx rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/components/time_controls.test.tsx index 02ba506e8abe14..83f5187f8a46c0 100644 --- a/x-pack/plugins/infra/public/pages/metrics/components/time_controls.test.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/time_controls.test.tsx @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -jest.mock('../../../utils/use_kibana_ui_setting', () => ({ +jest.mock('../../../../utils/use_kibana_ui_setting', () => ({ _esModule: true, useKibanaUiSetting: jest.fn(() => [ [ diff --git a/x-pack/plugins/infra/public/pages/metrics/components/time_controls.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/time_controls.tsx similarity index 91% rename from x-pack/plugins/infra/public/pages/metrics/components/time_controls.tsx rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/components/time_controls.tsx index cdbdc9bb7ecdb5..ef6486eac0fdb1 100644 --- a/x-pack/plugins/infra/public/pages/metrics/components/time_controls.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/time_controls.tsx @@ -6,10 +6,10 @@ import { EuiSuperDatePicker, OnRefreshChangeProps, OnTimeChangeProps } from '@elastic/eui'; import React, { useCallback } from 'react'; -import { euiStyled } from '../../../../../observability/public'; +import { euiStyled } from '../../../../../../observability/public'; import { MetricsTimeInput } from '../hooks/use_metrics_time'; -import { useKibanaUiSetting } from '../../../utils/use_kibana_ui_setting'; -import { mapKibanaQuickRangesToDatePickerRanges } from '../../../utils/map_timepicker_quickranges_to_datepicker_ranges'; +import { useKibanaUiSetting } from '../../../../utils/use_kibana_ui_setting'; +import { mapKibanaQuickRangesToDatePickerRanges } from '../../../../utils/map_timepicker_quickranges_to_datepicker_ranges'; interface MetricsTimeControlsProps { currentTimeRange: MetricsTimeInput; diff --git a/x-pack/plugins/infra/public/pages/metrics/containers/metadata_context.ts b/x-pack/plugins/infra/public/pages/metrics/metric_detail/containers/metadata_context.ts similarity index 84% rename from x-pack/plugins/infra/public/pages/metrics/containers/metadata_context.ts rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/containers/metadata_context.ts index 4ecf7fa15548cb..b8995d27d4dbe9 100644 --- a/x-pack/plugins/infra/public/pages/metrics/containers/metadata_context.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/containers/metadata_context.ts @@ -5,5 +5,5 @@ */ import React from 'react'; -import { InfraMetadata } from '../../../../common/http_api'; +import { InfraMetadata } from '../../../../../common/http_api'; export const MetadataContext = React.createContext(null); diff --git a/x-pack/plugins/infra/public/pages/metrics/hooks/metrics_time.test.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/metrics_time.test.tsx similarity index 100% rename from x-pack/plugins/infra/public/pages/metrics/hooks/metrics_time.test.tsx rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/metrics_time.test.tsx diff --git a/x-pack/plugins/infra/public/containers/metadata/use_metadata.ts b/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_metadata.ts similarity index 76% rename from x-pack/plugins/infra/public/containers/metadata/use_metadata.ts rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_metadata.ts index 1ba016195bef40..d2a20d449d89ac 100644 --- a/x-pack/plugins/infra/public/containers/metadata/use_metadata.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_metadata.ts @@ -8,12 +8,12 @@ import { useEffect } from 'react'; import { fold } from 'fp-ts/lib/Either'; import { identity } from 'fp-ts/lib/function'; import { pipe } from 'fp-ts/lib/pipeable'; -import { InfraMetadata, InfraMetadataRT } from '../../../common/http_api/metadata_api'; -import { useHTTPRequest } from '../../hooks/use_http_request'; -import { throwErrors, createPlainError } from '../../../common/runtime_types'; -import { InventoryMetric, InventoryItemType } from '../../../common/inventory_models/types'; -import { getFilteredMetrics } from './lib/get_filtered_metrics'; -import { MetricsTimeInput } from '../../pages/metrics/hooks/use_metrics_time'; +import { InfraMetadata, InfraMetadataRT } from '../../../../../common/http_api/metadata_api'; +import { useHTTPRequest } from '../../../../hooks/use_http_request'; +import { throwErrors, createPlainError } from '../../../../../common/runtime_types'; +import { InventoryMetric, InventoryItemType } from '../../../../../common/inventory_models/types'; +import { getFilteredMetrics } from '../lib/get_filtered_metrics'; +import { MetricsTimeInput } from './use_metrics_time'; export function useMetadata( nodeId: string, diff --git a/x-pack/plugins/infra/public/pages/metrics/hooks/use_metrics_time.ts b/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_metrics_time.ts similarity index 96% rename from x-pack/plugins/infra/public/pages/metrics/hooks/use_metrics_time.ts rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_metrics_time.ts index 2ed86863535ff7..98803ef2e69c6a 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hooks/use_metrics_time.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_metrics_time.ts @@ -12,8 +12,8 @@ import * as rt from 'io-ts'; import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; -import { useUrlState } from '../../../utils/use_url_state'; -import { replaceStateKeyInQueryString } from '../../../utils/url_state'; +import { useUrlState } from '../../../../utils/use_url_state'; +import { replaceStateKeyInQueryString } from '../../../../utils/url_state'; const parseRange = (range: MetricsTimeInput) => { const parsedFrom = dateMath.parse(range.from.toString()); diff --git a/x-pack/plugins/infra/public/containers/node_details/use_node_details.ts b/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_node_details.ts similarity index 75% rename from x-pack/plugins/infra/public/containers/node_details/use_node_details.ts rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_node_details.ts index 189c48ba1a70c4..3bb6c98c8eac06 100644 --- a/x-pack/plugins/infra/public/containers/node_details/use_node_details.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_node_details.ts @@ -6,14 +6,14 @@ import { fold } from 'fp-ts/lib/Either'; import { identity } from 'fp-ts/lib/function'; import { pipe } from 'fp-ts/lib/pipeable'; -import { throwErrors, createPlainError } from '../../../common/runtime_types'; -import { useHTTPRequest } from '../../hooks/use_http_request'; +import { throwErrors, createPlainError } from '../../../../../common/runtime_types'; +import { useHTTPRequest } from '../../../../hooks/use_http_request'; import { NodeDetailsMetricDataResponseRT, NodeDetailsMetricDataResponse, -} from '../../../common/http_api/node_details_api'; -import { InventoryMetric, InventoryItemType } from '../../../common/inventory_models/types'; -import { InfraTimerangeInput } from '../../../common/http_api/snapshot_api'; +} from '../../../../../common/http_api/node_details_api'; +import { InventoryMetric, InventoryItemType } from '../../../../../common/inventory_models/types'; +import { InfraTimerangeInput } from '../../../../../common/http_api/snapshot_api'; export function useNodeDetails( metrics: InventoryMetric[], diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx new file mode 100644 index 00000000000000..197a735f7fd1f2 --- /dev/null +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx @@ -0,0 +1,140 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { i18n } from '@kbn/i18n'; +import React, { useContext, useState } from 'react'; +import { euiStyled, EuiTheme, withTheme } from '../../../../../observability/public'; +import { DocumentTitle } from '../../../components/document_title'; +import { Header } from '../../../components/header'; +import { ColumnarPage, PageContent } from '../../../components/page'; +import { withMetricPageProviders } from './page_providers'; +import { useMetadata } from './hooks/use_metadata'; +import { Source } from '../../../containers/source'; +import { InfraLoadingPanel } from '../../../components/loading'; +import { findInventoryModel } from '../../../../common/inventory_models'; +import { NavItem } from './lib/side_nav_context'; +import { NodeDetailsPage } from './components/node_details_page'; +import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; +import { InventoryItemType } from '../../../../common/inventory_models/types'; +import { useMetricsTimeContext } from './hooks/use_metrics_time'; +import { useLinkProps } from '../../../hooks/use_link_props'; + +const DetailPageContent = euiStyled(PageContent)` + overflow: auto; + background-color: ${props => props.theme.eui.euiColorLightestShade}; +`; + +interface Props { + theme: EuiTheme; + match: { + params: { + type: string; + node: string; + }; + }; +} + +export const MetricDetail = withMetricPageProviders( + withTheme(({ match }: Props) => { + const uiCapabilities = useKibana().services.application?.capabilities; + const nodeId = match.params.node; + const nodeType = match.params.type as InventoryItemType; + const inventoryModel = findInventoryModel(nodeType); + const { sourceId } = useContext(Source.Context); + const { + timeRange, + parsedTimeRange, + setTimeRange, + refreshInterval, + setRefreshInterval, + isAutoReloading, + setAutoReload, + triggerRefresh, + } = useMetricsTimeContext(); + const { + name, + filteredRequiredMetrics, + loading: metadataLoading, + cloudId, + metadata, + } = useMetadata(nodeId, nodeType, inventoryModel.requiredMetrics, sourceId, parsedTimeRange); + + const [sideNav, setSideNav] = useState([]); + + const addNavItem = React.useCallback( + (item: NavItem) => { + if (!sideNav.some(n => n.id === item.id)) { + setSideNav([item, ...sideNav]); + } + }, + [sideNav] + ); + + const metricsLinkProps = useLinkProps({ + app: 'metrics', + pathname: '/', + }); + + const breadcrumbs = [ + { + ...metricsLinkProps, + text: i18n.translate('xpack.infra.header.infrastructureTitle', { + defaultMessage: 'Metrics', + }), + }, + { text: name }, + ]; + + if (metadataLoading && !filteredRequiredMetrics.length) { + return ( + + ); + } + + return ( + +
+ + + {metadata ? ( + + ) : null} + + + ); + }) +); diff --git a/x-pack/plugins/infra/public/containers/metadata/lib/get_filtered_metrics.ts b/x-pack/plugins/infra/public/pages/metrics/metric_detail/lib/get_filtered_metrics.ts similarity index 78% rename from x-pack/plugins/infra/public/containers/metadata/lib/get_filtered_metrics.ts rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/lib/get_filtered_metrics.ts index b485c90700145a..57ff182f01963d 100644 --- a/x-pack/plugins/infra/public/containers/metadata/lib/get_filtered_metrics.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/lib/get_filtered_metrics.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { InfraMetadataFeature } from '../../../../common/http_api/metadata_api'; -import { InventoryMetric } from '../../../../common/inventory_models/types'; -import { metrics } from '../../../../common/inventory_models/metrics'; +import { InfraMetadataFeature } from '../../../../../common/http_api/metadata_api'; +import { InventoryMetric } from '../../../../../common/inventory_models/types'; +import { metrics } from '../../../../../common/inventory_models/metrics'; export const getFilteredMetrics = ( requiredMetrics: InventoryMetric[], diff --git a/x-pack/plugins/infra/public/pages/metrics/lib/side_nav_context.ts b/x-pack/plugins/infra/public/pages/metrics/metric_detail/lib/side_nav_context.ts similarity index 100% rename from x-pack/plugins/infra/public/pages/metrics/lib/side_nav_context.ts rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/lib/side_nav_context.ts diff --git a/x-pack/plugins/infra/public/pages/metrics/page_providers.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/page_providers.tsx similarity index 91% rename from x-pack/plugins/infra/public/pages/metrics/page_providers.tsx rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/page_providers.tsx index d3f10adec06ed7..597977d9d2735d 100644 --- a/x-pack/plugins/infra/public/pages/metrics/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/page_providers.tsx @@ -6,7 +6,7 @@ import React from 'react'; -import { Source } from '../../containers/source'; +import { Source } from '../../../containers/source'; import { MetricsTimeProvider } from './hooks/use_metrics_time'; export const withMetricPageProviders = (Component: React.ComponentType) => ( diff --git a/x-pack/plugins/infra/public/pages/metrics/types.ts b/x-pack/plugins/infra/public/pages/metrics/metric_detail/types.ts similarity index 86% rename from x-pack/plugins/infra/public/pages/metrics/types.ts rename to x-pack/plugins/infra/public/pages/metrics/metric_detail/types.ts index 2cc261df289772..3ec57e23a425d2 100644 --- a/x-pack/plugins/infra/public/pages/metrics/types.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/types.ts @@ -5,10 +5,10 @@ */ import rt from 'io-ts'; -import { EuiTheme } from '../../../../observability/public'; -import { InventoryFormatterTypeRT } from '../../../common/inventory_models/types'; +import { EuiTheme } from '../../../../../observability/public'; +import { InventoryFormatterTypeRT } from '../../../../common/inventory_models/types'; import { MetricsTimeInput } from './hooks/use_metrics_time'; -import { NodeDetailsMetricData } from '../../../common/http_api/node_details_api'; +import { NodeDetailsMetricData } from '../../../../common/http_api/node_details_api'; export interface LayoutProps { metrics?: NodeDetailsMetricData[]; diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/aggregation.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/aggregation.tsx similarity index 89% rename from x-pack/plugins/infra/public/components/metrics_explorer/aggregation.tsx rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/aggregation.tsx index 76fa519ab37567..0c0f7b33b3a4a0 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/aggregation.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/aggregation.tsx @@ -8,12 +8,12 @@ import { EuiSelect } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { useCallback } from 'react'; -import { MetricsExplorerAggregation } from '../../../common/http_api/metrics_explorer'; -import { MetricsExplorerOptions } from '../../containers/metrics_explorer/use_metrics_explorer_options'; +import { MetricsExplorerAggregation } from '../../../../../common/http_api/metrics_explorer'; +import { MetricsExplorerOptions } from '../hooks/use_metrics_explorer_options'; import { metricsExplorerAggregationRT, METRIC_EXPLORER_AGGREGATIONS, -} from '../../../common/http_api/metrics_explorer'; +} from '../../../../../common/http_api/metrics_explorer'; interface Props { options: MetricsExplorerOptions; diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/chart.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart.tsx similarity index 92% rename from x-pack/plugins/infra/public/components/metrics_explorer/chart.tsx rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart.tsx index 43b08f45eed34e..089e1abfc4c912 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/chart.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart.tsx @@ -10,24 +10,24 @@ import { EuiTitle, EuiToolTip, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { Axis, Chart, niceTimeFormatter, Position, Settings, TooltipValue } from '@elastic/charts'; import { first, last } from 'lodash'; import moment from 'moment'; -import { MetricsExplorerSeries } from '../../../common/http_api/metrics_explorer'; +import { MetricsExplorerSeries } from '../../../../../common/http_api/metrics_explorer'; import { MetricsExplorerOptions, MetricsExplorerTimeOptions, MetricsExplorerYAxisMode, MetricsExplorerChartOptions, -} from '../../containers/metrics_explorer/use_metrics_explorer_options'; -import { euiStyled } from '../../../../observability/public'; +} from '../hooks/use_metrics_explorer_options'; +import { euiStyled } from '../../../../../../observability/public'; import { createFormatterForMetric } from './helpers/create_formatter_for_metric'; import { MetricExplorerSeriesChart } from './series_chart'; import { MetricsExplorerChartContextMenu } from './chart_context_menu'; -import { SourceQuery } from '../../graphql/types'; +import { SourceQuery } from '../../../../graphql/types'; import { MetricsExplorerEmptyChart } from './empty_chart'; import { MetricsExplorerNoMetrics } from './no_metrics'; import { getChartTheme } from './helpers/get_chart_theme'; -import { useKibanaUiSetting } from '../../utils/use_kibana_ui_setting'; +import { useKibanaUiSetting } from '../../../../utils/use_kibana_ui_setting'; import { calculateDomain } from './helpers/calculate_domain'; -import { useKibana, useUiSetting } from '../../../../../../src/plugins/kibana_react/public'; +import { useKibana, useUiSetting } from '../../../../../../../../src/plugins/kibana_react/public'; interface Props { title?: string | null; diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/chart_context_menu.test.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart_context_menu.test.tsx similarity index 96% rename from x-pack/plugins/infra/public/components/metrics_explorer/chart_context_menu.test.tsx rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart_context_menu.test.tsx index 8ffef269a42ea1..5c0abb8fd845f2 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/chart_context_menu.test.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart_context_menu.test.tsx @@ -7,9 +7,14 @@ import React from 'react'; import { MetricsExplorerChartContextMenu, createNodeDetailLink, Props } from './chart_context_menu'; import { ReactWrapper, mount } from 'enzyme'; -import { options, source, timeRange, chartOptions } from '../../utils/fixtures/metrics_explorer'; +import { + options, + source, + timeRange, + chartOptions, +} from '../../../../utils/fixtures/metrics_explorer'; import { Capabilities } from 'src/core/public'; -import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public'; +import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public'; import { coreMock } from 'src/core/public/mocks'; const coreStartMock = coreMock.createStart(); diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/chart_context_menu.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart_context_menu.tsx similarity index 91% rename from x-pack/plugins/infra/public/components/metrics_explorer/chart_context_menu.tsx rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart_context_menu.tsx index 75a04cbe9799e5..31086a21ca13f8 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/chart_context_menu.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart_context_menu.tsx @@ -14,18 +14,18 @@ import { } from '@elastic/eui'; import DateMath from '@elastic/datemath'; import { Capabilities } from 'src/core/public'; -import { MetricsExplorerSeries } from '../../../common/http_api/metrics_explorer'; +import { AlertFlyout } from '../../../../components/alerting/metrics/alert_flyout'; +import { MetricsExplorerSeries } from '../../../../../common/http_api/metrics_explorer'; import { MetricsExplorerOptions, MetricsExplorerTimeOptions, MetricsExplorerChartOptions, -} from '../../containers/metrics_explorer/use_metrics_explorer_options'; +} from '../hooks/use_metrics_explorer_options'; import { createTSVBLink } from './helpers/create_tsvb_link'; -import { getNodeDetailUrl } from '../../pages/link_to/redirect_to_node_detail'; -import { SourceConfiguration } from '../../utils/source_configuration'; -import { InventoryItemType } from '../../../common/inventory_models/types'; -import { AlertFlyout } from '../alerting/metrics/alert_flyout'; -import { useLinkProps } from '../../hooks/use_link_props'; +import { getNodeDetailUrl } from '../../../link_to/redirect_to_node_detail'; +import { SourceConfiguration } from '../../../../utils/source_configuration'; +import { InventoryItemType } from '../../../../../common/inventory_models/types'; +import { useLinkProps } from '../../../../hooks/use_link_props'; export interface Props { options: MetricsExplorerOptions; diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/chart_options.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart_options.tsx similarity index 98% rename from x-pack/plugins/infra/public/components/metrics_explorer/chart_options.tsx rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart_options.tsx index 657c4cea30f3ab..ba28075ededb6e 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/chart_options.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart_options.tsx @@ -19,7 +19,7 @@ import { MetricsExplorerChartOptions as ChartOptions, MetricsExplorerYAxisMode, MetricsExplorerChartType, -} from '../../containers/metrics_explorer/use_metrics_explorer_options'; +} from '../hooks/use_metrics_explorer_options'; interface Props { chartOptions: ChartOptions; diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/charts.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/charts.tsx similarity index 92% rename from x-pack/plugins/infra/public/components/metrics_explorer/charts.tsx rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/charts.tsx index 64e7b27f5722f0..ecec1163108756 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/charts.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/charts.tsx @@ -8,16 +8,16 @@ import { EuiButton, EuiFlexGrid, EuiFlexItem, EuiText, EuiHorizontalRule } from import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import React from 'react'; -import { MetricsExplorerResponse } from '../../../common/http_api/metrics_explorer'; +import { MetricsExplorerResponse } from '../../../../../common/http_api/metrics_explorer'; import { MetricsExplorerOptions, MetricsExplorerTimeOptions, MetricsExplorerChartOptions, -} from '../../containers/metrics_explorer/use_metrics_explorer_options'; -import { InfraLoadingPanel } from '../loading'; -import { NoData } from '../empty_states/no_data'; +} from '../hooks/use_metrics_explorer_options'; +import { InfraLoadingPanel } from '../../../../components/loading'; +import { NoData } from '../../../../components/empty_states/no_data'; import { MetricsExplorerChart } from './chart'; -import { SourceQuery } from '../../graphql/types'; +import { SourceQuery } from '../../../../graphql/types'; interface Props { loading: boolean; diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/empty_chart.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/empty_chart.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/metrics_explorer/empty_chart.tsx rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/empty_chart.tsx diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/group_by.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/group_by.tsx similarity index 72% rename from x-pack/plugins/infra/public/components/metrics_explorer/group_by.tsx rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/group_by.tsx index 750894fd0188bc..bfe8ddb2e08291 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/group_by.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/group_by.tsx @@ -9,8 +9,7 @@ import { i18n } from '@kbn/i18n'; import React, { useCallback } from 'react'; import { IFieldType } from 'src/plugins/data/public'; -import { MetricsExplorerOptions } from '../../containers/metrics_explorer/use_metrics_explorer_options'; -import { isDisplayable } from '../../utils/is_displayable'; +import { MetricsExplorerOptions } from '../hooks/use_metrics_explorer_options'; interface Props { options: MetricsExplorerOptions; @@ -27,18 +26,6 @@ export const MetricsExplorerGroupBy = ({ options, onChange, fields }: Props) => [onChange] ); - const metricPrefixes = options.metrics - .map( - metric => - (metric.field && - metric.field - .split(/\./) - .slice(0, 2) - .join('.')) || - null - ) - .filter(metric => metric) as string[]; - return ( singleSelection={true} selectedOptions={(options.groupBy && [{ label: options.groupBy }]) || []} options={fields - .filter(f => isDisplayable(f, metricPrefixes) && f.aggregatable && f.type === 'string') + .filter(f => f.aggregatable && f.type === 'string') .map(f => ({ label: f.name }))} onChange={handleChange} isClearable={true} diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/calculate_domain.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/calculate_domain.ts similarity index 87% rename from x-pack/plugins/infra/public/components/metrics_explorer/helpers/calculate_domain.ts rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/calculate_domain.ts index 90569854b833b3..811486d355f2e5 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/calculate_domain.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/calculate_domain.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ import { min, max, sum, isNumber } from 'lodash'; -import { MetricsExplorerSeries } from '../../../../common/http_api/metrics_explorer'; -import { MetricsExplorerOptionsMetric } from '../../../containers/metrics_explorer/use_metrics_explorer_options'; +import { MetricsExplorerSeries } from '../../../../../../common/http_api/metrics_explorer'; +import { MetricsExplorerOptionsMetric } from '../../hooks/use_metrics_explorer_options'; const getMin = (values: Array) => { const minValue = min(values); diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/calculate_domian.test.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/calculate_domian.test.ts similarity index 85% rename from x-pack/plugins/infra/public/components/metrics_explorer/helpers/calculate_domian.test.ts rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/calculate_domian.test.ts index 4b45534d41db82..f94c6b6156ae4b 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/calculate_domian.test.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/calculate_domian.test.ts @@ -5,9 +5,9 @@ */ import { calculateDomain } from './calculate_domain'; -import { MetricsExplorerSeries } from '../../../../common/http_api/metrics_explorer'; -import { MetricsExplorerOptionsMetric } from '../../../containers/metrics_explorer/use_metrics_explorer_options'; -import { MetricsExplorerColor } from '../../../../common/color_palette'; +import { MetricsExplorerSeries } from '../../../../../../common/http_api/metrics_explorer'; +import { MetricsExplorerOptionsMetric } from '../../hooks/use_metrics_explorer_options'; +import { MetricsExplorerColor } from '../../../../../../common/color_palette'; describe('calculateDomain()', () => { const series: MetricsExplorerSeries = { id: 'test-01', diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_formatter_for_metric.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_formatter_for_metric.ts similarity index 76% rename from x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_formatter_for_metric.ts rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_formatter_for_metric.ts index 33ec2ce2715a3c..d07a6b45f02bef 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_formatter_for_metric.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_formatter_for_metric.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { MetricsExplorerMetric } from '../../../../common/http_api/metrics_explorer'; -import { createFormatter } from '../../../utils/formatters'; -import { InfraFormatterType } from '../../../lib/lib'; +import { MetricsExplorerMetric } from '../../../../../../common/http_api/metrics_explorer'; +import { createFormatter } from '../../../../../utils/formatters'; +import { InfraFormatterType } from '../../../../../lib/lib'; import { metricToFormat } from './metric_to_format'; export const createFormatterForMetric = (metric?: MetricsExplorerMetric) => { if (metric && metric.field) { diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_formatter_for_metrics.test.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_formatter_for_metrics.test.ts similarity index 94% rename from x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_formatter_for_metrics.test.ts rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_formatter_for_metrics.test.ts index ec41e90e441a44..e039d5d4b3eeb4 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_formatter_for_metrics.test.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_formatter_for_metrics.test.ts @@ -5,7 +5,7 @@ */ import { createFormatterForMetric } from './create_formatter_for_metric'; -import { MetricsExplorerMetric } from '../../../../common/http_api/metrics_explorer'; +import { MetricsExplorerMetric } from '../../../../../../common/http_api/metrics_explorer'; describe('createFormatterForMetric()', () => { it('should just work for count', () => { diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_metric_label.test.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_metric_label.test.ts similarity index 88% rename from x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_metric_label.test.ts rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_metric_label.test.ts index cbf6904d246c70..367c472f414e42 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_metric_label.test.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_metric_label.test.ts @@ -5,7 +5,7 @@ */ import { createMetricLabel } from './create_metric_label'; -import { MetricsExplorerMetric } from '../../../../common/http_api/metrics_explorer'; +import { MetricsExplorerMetric } from '../../../../../../common/http_api/metrics_explorer'; describe('createMetricLabel()', () => { it('should work with metrics with fields', () => { diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_metric_label.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_metric_label.ts similarity index 80% rename from x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_metric_label.ts rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_metric_label.ts index b6453a81317b13..1607302a6259a5 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_metric_label.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_metric_label.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { MetricsExplorerMetric } from '../../../../common/http_api/metrics_explorer'; +import { MetricsExplorerMetric } from '../../../../../../common/http_api/metrics_explorer'; export const createMetricLabel = (metric: MetricsExplorerMetric) => { return `${metric.aggregation}(${metric.field || ''})`; diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_tsvb_link.test.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_tsvb_link.test.ts similarity index 97% rename from x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_tsvb_link.test.ts rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_tsvb_link.test.ts index 05637642b8dd9e..47bb4c8c57716d 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_tsvb_link.test.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_tsvb_link.test.ts @@ -5,14 +5,19 @@ */ import { createTSVBLink, createFilterFromOptions } from './create_tsvb_link'; -import { source, options, timeRange, chartOptions } from '../../../utils/fixtures/metrics_explorer'; +import { + source, + options, + timeRange, + chartOptions, +} from '../../../../../utils/fixtures/metrics_explorer'; import uuid from 'uuid'; import { OutputBuffer } from 'uuid/interfaces'; import { MetricsExplorerYAxisMode, MetricsExplorerChartType, -} from '../../../containers/metrics_explorer/use_metrics_explorer_options'; -import { MetricsExplorerOptions } from '../../../containers/metrics_explorer/use_metrics_explorer_options'; +} from '../../hooks/use_metrics_explorer_options'; +import { MetricsExplorerOptions } from '../../hooks/use_metrics_explorer_options'; jest.mock('uuid'); const mockedUuid = uuid as jest.Mocked; diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_tsvb_link.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_tsvb_link.ts similarity index 91% rename from x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_tsvb_link.ts rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_tsvb_link.ts index 20706f563ec637..559422584f579a 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/create_tsvb_link.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_tsvb_link.ts @@ -7,8 +7,8 @@ import { encode } from 'rison-node'; import uuid from 'uuid'; import { set } from 'lodash'; -import { colorTransformer, MetricsExplorerColor } from '../../../../common/color_palette'; -import { MetricsExplorerSeries } from '../../../../common/http_api/metrics_explorer'; +import { colorTransformer, MetricsExplorerColor } from '../../../../../../common/color_palette'; +import { MetricsExplorerSeries } from '../../../../../../common/http_api/metrics_explorer'; import { MetricsExplorerOptions, MetricsExplorerOptionsMetric, @@ -16,12 +16,12 @@ import { MetricsExplorerChartOptions, MetricsExplorerYAxisMode, MetricsExplorerChartType, -} from '../../../containers/metrics_explorer/use_metrics_explorer_options'; +} from '../../hooks/use_metrics_explorer_options'; import { metricToFormat } from './metric_to_format'; -import { InfraFormatterType } from '../../../lib/lib'; -import { SourceQuery } from '../../../graphql/types'; +import { InfraFormatterType } from '../../../../../lib/lib'; +import { SourceQuery } from '../../../../../graphql/types'; import { createMetricLabel } from './create_metric_label'; -import { LinkDescriptor } from '../../../hooks/use_link_props'; +import { LinkDescriptor } from '../../../../../hooks/use_link_props'; export const metricsExplorerMetricToTSVBMetric = (metric: MetricsExplorerOptionsMetric) => { if (metric.aggregation === 'rate') { diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/get_chart_theme.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/get_chart_theme.ts similarity index 100% rename from x-pack/plugins/infra/public/components/metrics_explorer/helpers/get_chart_theme.ts rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/get_chart_theme.ts diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/metric_to_format.test.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/metric_to_format.test.ts similarity index 90% rename from x-pack/plugins/infra/public/components/metrics_explorer/helpers/metric_to_format.test.ts rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/metric_to_format.test.ts index 4cb27b4fb65c3e..6b27627a9fb5b2 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/metric_to_format.test.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/metric_to_format.test.ts @@ -5,8 +5,8 @@ */ import { metricToFormat } from './metric_to_format'; -import { MetricsExplorerMetric } from '../../../../common/http_api/metrics_explorer'; -import { InfraFormatterType } from '../../../lib/lib'; +import { MetricsExplorerMetric } from '../../../../../../common/http_api/metrics_explorer'; +import { InfraFormatterType } from '../../../../../lib/lib'; describe('metricToFormat()', () => { it('should just work for numeric metrics', () => { const metric: MetricsExplorerMetric = { aggregation: 'avg', field: 'system.load.1' }; diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/metric_to_format.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/metric_to_format.ts similarity index 82% rename from x-pack/plugins/infra/public/components/metrics_explorer/helpers/metric_to_format.ts rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/metric_to_format.ts index 63272c86a5dc79..1dbbf97a32217b 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/helpers/metric_to_format.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/metric_to_format.ts @@ -5,8 +5,8 @@ */ import { last } from 'lodash'; -import { MetricsExplorerMetric } from '../../../../common/http_api/metrics_explorer'; -import { InfraFormatterType } from '../../../lib/lib'; +import { MetricsExplorerMetric } from '../../../../../../common/http_api/metrics_explorer'; +import { InfraFormatterType } from '../../../../../lib/lib'; export const metricToFormat = (metric?: MetricsExplorerMetric) => { if (metric && metric.field) { const suffix = last(metric.field.split(/\./)); diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/kuery_bar.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx similarity index 84% rename from x-pack/plugins/infra/public/components/metrics_explorer/kuery_bar.tsx rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx index dcc160d05b6ad9..e9826e1ff39552 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/kuery_bar.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx @@ -7,10 +7,9 @@ import { i18n } from '@kbn/i18n'; import React, { useEffect, useState } from 'react'; -import { WithKueryAutocompletion } from '../../containers/with_kuery_autocompletion'; -import { AutocompleteField } from '../autocomplete_field'; -import { isDisplayable } from '../../utils/is_displayable'; -import { esKuery, IIndexPattern } from '../../../../../../src/plugins/data/public'; +import { WithKueryAutocompletion } from '../../../../containers/with_kuery_autocompletion'; +import { AutocompleteField } from '../../../../components/autocomplete_field'; +import { esKuery, IIndexPattern } from '../../../../../../../../src/plugins/data/public'; interface Props { derivedIndexPattern: IIndexPattern; @@ -51,7 +50,7 @@ export const MetricsExplorerKueryBar = ({ const filteredDerivedIndexPattern = { ...derivedIndexPattern, - fields: derivedIndexPattern.fields.filter(field => isDisplayable(field)), + fields: derivedIndexPattern.fields, }; const defaultPlaceholder = i18n.translate( diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/metrics.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/metrics.tsx similarity index 85% rename from x-pack/plugins/infra/public/components/metrics_explorer/metrics.tsx rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/metrics.tsx index 79d4122733c551..612735e2ba772e 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/metrics.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/metrics.tsx @@ -9,10 +9,9 @@ import { i18n } from '@kbn/i18n'; import React, { useCallback, useState } from 'react'; import { IFieldType } from 'src/plugins/data/public'; -import { colorTransformer, MetricsExplorerColor } from '../../../common/color_palette'; -import { MetricsExplorerMetric } from '../../../common/http_api/metrics_explorer'; -import { MetricsExplorerOptions } from '../../containers/metrics_explorer/use_metrics_explorer_options'; -import { isDisplayable } from '../../utils/is_displayable'; +import { colorTransformer, MetricsExplorerColor } from '../../../../../common/color_palette'; +import { MetricsExplorerMetric } from '../../../../../common/http_api/metrics_explorer'; +import { MetricsExplorerOptions } from '../hooks/use_metrics_explorer_options'; interface Props { autoFocus?: boolean; @@ -54,9 +53,7 @@ export const MetricsExplorerMetrics = ({ options, onChange, fields, autoFocus = [onChange, options.aggregation, colors] ); - const comboOptions = fields - .filter(field => isDisplayable(field)) - .map(field => ({ label: field.name, value: field.name })); + const comboOptions = fields.map(field => ({ label: field.name, value: field.name })); const selectedOptions = options.metrics .filter(m => m.aggregation !== 'count') .map(metric => ({ diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/no_metrics.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/no_metrics.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/metrics_explorer/no_metrics.tsx rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/no_metrics.tsx diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/series_chart.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/series_chart.tsx similarity index 93% rename from x-pack/plugins/infra/public/components/metrics_explorer/series_chart.tsx rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/series_chart.tsx index ed7a994dd2bbec..ad7ce83539526a 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/series_chart.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/series_chart.tsx @@ -13,13 +13,13 @@ import { AreaSeriesStyle, BarSeriesStyle, } from '@elastic/charts'; -import { MetricsExplorerSeries } from '../../../common/http_api/metrics_explorer'; -import { colorTransformer, MetricsExplorerColor } from '../../../common/color_palette'; +import { MetricsExplorerSeries } from '../../../../../common/http_api/metrics_explorer'; +import { colorTransformer, MetricsExplorerColor } from '../../../../../common/color_palette'; import { createMetricLabel } from './helpers/create_metric_label'; import { MetricsExplorerOptionsMetric, MetricsExplorerChartType, -} from '../../containers/metrics_explorer/use_metrics_explorer_options'; +} from '../hooks/use_metrics_explorer_options'; interface Props { metric: MetricsExplorerOptionsMetric; diff --git a/x-pack/plugins/infra/public/components/metrics_explorer/toolbar.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/toolbar.tsx similarity index 88% rename from x-pack/plugins/infra/public/components/metrics_explorer/toolbar.tsx rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/toolbar.tsx index 0fbb0b6acad176..81971bd31a9739 100644 --- a/x-pack/plugins/infra/public/components/metrics_explorer/toolbar.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/toolbar.tsx @@ -11,23 +11,23 @@ import { IIndexPattern } from 'src/plugins/data/public'; import { MetricsExplorerMetric, MetricsExplorerAggregation, -} from '../../../common/http_api/metrics_explorer'; +} from '../../../../../common/http_api/metrics_explorer'; import { MetricsExplorerOptions, MetricsExplorerTimeOptions, MetricsExplorerChartOptions, -} from '../../containers/metrics_explorer/use_metrics_explorer_options'; -import { Toolbar } from '../eui/toolbar'; +} from '../hooks/use_metrics_explorer_options'; +import { Toolbar } from '../../../../components/eui/toolbar'; import { MetricsExplorerKueryBar } from './kuery_bar'; import { MetricsExplorerMetrics } from './metrics'; import { MetricsExplorerGroupBy } from './group_by'; import { MetricsExplorerAggregationPicker } from './aggregation'; import { MetricsExplorerChartOptions as MetricsExplorerChartOptionsComponent } from './chart_options'; -import { SavedViewsToolbarControls } from '../saved_views/toolbar_control'; -import { MetricExplorerViewState } from '../../pages/infrastructure/metrics_explorer/use_metric_explorer_state'; -import { metricsExplorerViewSavedObjectType } from '../../../common/saved_objects/metrics_explorer_view'; -import { useKibanaUiSetting } from '../../utils/use_kibana_ui_setting'; -import { mapKibanaQuickRangesToDatePickerRanges } from '../../utils/map_timepicker_quickranges_to_datepicker_ranges'; +import { SavedViewsToolbarControls } from '../../../../components/saved_views/toolbar_control'; +import { MetricExplorerViewState } from '../hooks/use_metric_explorer_state'; +import { metricsExplorerViewSavedObjectType } from '../../../../../common/saved_objects/metrics_explorer_view'; +import { useKibanaUiSetting } from '../../../../utils/use_kibana_ui_setting'; +import { mapKibanaQuickRangesToDatePickerRanges } from '../../../../utils/map_timepicker_quickranges_to_datepicker_ranges'; interface Props { derivedIndexPattern: IIndexPattern; diff --git a/x-pack/plugins/infra/public/pages/infrastructure/metrics_explorer/use_metric_explorer_state.test.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.test.tsx similarity index 96% rename from x-pack/plugins/infra/public/pages/infrastructure/metrics_explorer/use_metric_explorer_state.test.tsx rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.test.tsx index 874ac0987023bd..f0734f76cfacd9 100644 --- a/x-pack/plugins/infra/public/pages/infrastructure/metrics_explorer/use_metric_explorer_state.test.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.test.tsx @@ -6,14 +6,14 @@ import { renderHook, act } from '@testing-library/react-hooks'; import { useMetricsExplorerState } from './use_metric_explorer_state'; -import { MetricsExplorerOptionsContainer } from '../../../containers/metrics_explorer/use_metrics_explorer_options'; +import { MetricsExplorerOptionsContainer } from './use_metrics_explorer_options'; import React from 'react'; import { source, derivedIndexPattern, resp, createSeries, -} from '../../../utils/fixtures/metrics_explorer'; +} from '../../../../utils/fixtures/metrics_explorer'; const renderUseMetricsExplorerStateHook = () => renderHook(props => useMetricsExplorerState(props.source, props.derivedIndexPattern), { @@ -27,7 +27,7 @@ const renderUseMetricsExplorerStateHook = () => const mockedUseMetricsExplorerData = jest.fn(); -jest.mock('../../../containers/metrics_explorer/use_metrics_explorer_data', () => { +jest.mock('./use_metrics_explorer_data', () => { return { useMetricsExplorerData: () => { return mockedUseMetricsExplorerData(); diff --git a/x-pack/plugins/infra/public/pages/infrastructure/metrics_explorer/use_metric_explorer_state.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.ts similarity index 92% rename from x-pack/plugins/infra/public/pages/infrastructure/metrics_explorer/use_metric_explorer_state.ts rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.ts index 88e6d9d800661d..8a9ed901de0b06 100644 --- a/x-pack/plugins/infra/public/pages/infrastructure/metrics_explorer/use_metric_explorer_state.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.ts @@ -9,15 +9,15 @@ import { IIndexPattern } from 'src/plugins/data/public'; import { MetricsExplorerMetric, MetricsExplorerAggregation, -} from '../../../../common/http_api/metrics_explorer'; -import { useMetricsExplorerData } from '../../../containers/metrics_explorer/use_metrics_explorer_data'; +} from '../../../../../common/http_api/metrics_explorer'; +import { useMetricsExplorerData } from './use_metrics_explorer_data'; import { MetricsExplorerOptionsContainer, MetricsExplorerChartOptions, MetricsExplorerTimeOptions, MetricsExplorerOptions, -} from '../../../containers/metrics_explorer/use_metrics_explorer_options'; -import { SourceQuery } from '../../../graphql/types'; +} from './use_metrics_explorer_options'; +import { SourceQuery } from '../../../../graphql/types'; export interface MetricExplorerViewState { chartOptions: MetricsExplorerChartOptions; diff --git a/x-pack/plugins/infra/public/containers/metrics_explorer/use_metrics_explorer_data.test.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.test.tsx similarity index 96% rename from x-pack/plugins/infra/public/containers/metrics_explorer/use_metrics_explorer_data.test.tsx rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.test.tsx index bbc8778545b4a0..94edab54fb71e9 100644 --- a/x-pack/plugins/infra/public/containers/metrics_explorer/use_metrics_explorer_data.test.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { useMetricsExplorerData } from './use_metrics_explorer_data'; import { renderHook } from '@testing-library/react-hooks'; -import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public'; +import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public'; import { options, @@ -17,7 +17,7 @@ import { timeRange, resp, createSeries, -} from '../../utils/fixtures/metrics_explorer'; +} from '../../../../utils/fixtures/metrics_explorer'; const mockedFetch = jest.fn(); @@ -54,7 +54,7 @@ const renderUseMetricsExplorerDataHook = () => { ); }; -jest.mock('../../utils/kuery', () => { +jest.mock('../../../../utils/kuery', () => { return { convertKueryToElasticSearchQuery: (query: string) => query, }; diff --git a/x-pack/plugins/infra/public/containers/metrics_explorer/use_metrics_explorer_data.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.ts similarity index 91% rename from x-pack/plugins/infra/public/containers/metrics_explorer/use_metrics_explorer_data.ts rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.ts index b32496fbf30a11..93aacb586a5cde 100644 --- a/x-pack/plugins/infra/public/containers/metrics_explorer/use_metrics_explorer_data.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.ts @@ -8,15 +8,15 @@ import DateMath from '@elastic/datemath'; import { isEqual } from 'lodash'; import { useEffect, useState } from 'react'; import { IIndexPattern } from 'src/plugins/data/public'; -import { SourceQuery } from '../../../common/graphql/types'; +import { SourceQuery } from '../../../../../common/graphql/types'; import { MetricsExplorerResponse, metricsExplorerResponseRT, -} from '../../../common/http_api/metrics_explorer'; -import { convertKueryToElasticSearchQuery } from '../../utils/kuery'; +} from '../../../../../common/http_api/metrics_explorer'; +import { convertKueryToElasticSearchQuery } from '../../../../utils/kuery'; import { MetricsExplorerOptions, MetricsExplorerTimeOptions } from './use_metrics_explorer_options'; -import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; -import { decodeOrThrow } from '../../../common/runtime_types'; +import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; function isSameOptions(current: MetricsExplorerOptions, next: MetricsExplorerOptions) { return isEqual(current, next); diff --git a/x-pack/plugins/infra/public/containers/metrics_explorer/use_metrics_explorer_options.test.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.test.tsx similarity index 100% rename from x-pack/plugins/infra/public/containers/metrics_explorer/use_metrics_explorer_options.test.tsx rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.test.tsx diff --git a/x-pack/plugins/infra/public/containers/metrics_explorer/use_metrics_explorer_options.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts similarity index 96% rename from x-pack/plugins/infra/public/containers/metrics_explorer/use_metrics_explorer_options.ts rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts index 2b802af8e8c15f..9d124a6af80123 100644 --- a/x-pack/plugins/infra/public/containers/metrics_explorer/use_metrics_explorer_options.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts @@ -6,11 +6,11 @@ import createContainer from 'constate'; import { useState, useEffect, Dispatch, SetStateAction } from 'react'; -import { MetricsExplorerColor } from '../../../common/color_palette'; +import { MetricsExplorerColor } from '../../../../../common/color_palette'; import { MetricsExplorerAggregation, MetricsExplorerMetric, -} from '../../../common/http_api/metrics_explorer'; +} from '../../../../../common/http_api/metrics_explorer'; export type MetricsExplorerOptionsMetric = MetricsExplorerMetric & { color?: MetricsExplorerColor; diff --git a/x-pack/plugins/infra/public/pages/infrastructure/metrics_explorer/index.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx similarity index 92% rename from x-pack/plugins/infra/public/pages/infrastructure/metrics_explorer/index.tsx rename to x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx index 0999cea59731ca..a213671e9436eb 100644 --- a/x-pack/plugins/infra/public/pages/infrastructure/metrics_explorer/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx @@ -9,11 +9,11 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import { IIndexPattern } from 'src/plugins/data/public'; import { DocumentTitle } from '../../../components/document_title'; -import { MetricsExplorerCharts } from '../../../components/metrics_explorer/charts'; -import { MetricsExplorerToolbar } from '../../../components/metrics_explorer/toolbar'; +import { MetricsExplorerCharts } from './components/charts'; +import { MetricsExplorerToolbar } from './components/toolbar'; import { SourceQuery } from '../../../../common/graphql/types'; import { NoData } from '../../../components/empty_states'; -import { useMetricsExplorerState } from './use_metric_explorer_state'; +import { useMetricsExplorerState } from './hooks/use_metric_explorer_state'; import { useTrackPageview } from '../../../../../observability/public'; interface MetricsExplorerPageProps { diff --git a/x-pack/plugins/infra/public/pages/infrastructure/settings.tsx b/x-pack/plugins/infra/public/pages/metrics/settings.tsx similarity index 100% rename from x-pack/plugins/infra/public/pages/infrastructure/settings.tsx rename to x-pack/plugins/infra/public/pages/metrics/settings.tsx diff --git a/x-pack/plugins/infra/public/routers/metrics_router.tsx b/x-pack/plugins/infra/public/routers/metrics_router.tsx index 7cb9de65e72917..0e427150a46cc6 100644 --- a/x-pack/plugins/infra/public/routers/metrics_router.tsx +++ b/x-pack/plugins/infra/public/routers/metrics_router.tsx @@ -8,12 +8,12 @@ import React from 'react'; import { Route, Router, Switch } from 'react-router-dom'; import { NotFoundPage } from '../pages/404'; -import { InfrastructurePage } from '../pages/infrastructure'; -import { LinkToMetricsPage } from '../pages/link_to'; -import { MetricDetail } from '../pages/metrics'; +import { InfrastructurePage } from '../pages/metrics'; +import { MetricDetail } from '../pages/metrics/metric_detail'; import { RedirectWithQueryParams } from '../utils/redirect_with_query_params'; import { useKibana } from '../../../../../src/plugins/kibana_react/public'; import { AppRouter } from './index'; +import { LinkToMetricsPage } from '../pages/link_to'; export const MetricsRouter: AppRouter = ({ history }) => { const uiCapabilities = useKibana().services.application?.capabilities; diff --git a/x-pack/plugins/infra/public/utils/fixtures/metrics_explorer.ts b/x-pack/plugins/infra/public/utils/fixtures/metrics_explorer.ts index e39d6f785d53e2..15159ad45c7f33 100644 --- a/x-pack/plugins/infra/public/utils/fixtures/metrics_explorer.ts +++ b/x-pack/plugins/infra/public/utils/fixtures/metrics_explorer.ts @@ -14,7 +14,7 @@ import { MetricsExplorerChartType, MetricsExplorerYAxisMode, MetricsExplorerChartOptions, -} from '../../containers/metrics_explorer/use_metrics_explorer_options'; +} from '../../pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options'; export const options: MetricsExplorerOptions = { limit: 3, diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/alpha_messaging.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/alpha_messaging.tsx new file mode 100644 index 00000000000000..0f3ddee29fa443 --- /dev/null +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/alpha_messaging.tsx @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React from 'react'; +import styled from 'styled-components'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiText } from '@elastic/eui'; + +const Message = styled(EuiText).attrs(props => ({ + color: 'subdued', + textAlign: 'center', +}))` + padding: ${props => props.theme.eui.paddingSizes.m}; +`; + +export const AlphaMessaging: React.FC<{}> = () => ( + +

+ + + + + {' – '} + + +

+
+); diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/header.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/header.tsx index 1aab6d901a9926..ceb87fb048ae3c 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/header.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/header.tsx @@ -31,7 +31,7 @@ const Tabs = styled(EuiTabs)` `; export interface HeaderProps { - restrictHeaderWidth?: number; + maxWidth?: number; leftColumn?: JSX.Element; rightColumn?: JSX.Element; rightColumnGrow?: EuiFlexItemProps['grow']; @@ -52,10 +52,10 @@ export const Header: React.FC = ({ rightColumn, rightColumnGrow, tabs, - restrictHeaderWidth, + maxWidth, }) => ( - + = ({ section, childre {children} + ); }; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/with_header.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/with_header.tsx index c77a50d95dca3c..d5ce5e17ad84ec 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/with_header.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/with_header.tsx @@ -14,12 +14,18 @@ const Page = styled(EuiPage)` interface Props extends HeaderProps { restrictWidth?: number; + restrictHeaderWidth?: number; children?: React.ReactNode; } -export const WithHeaderLayout: React.FC = ({ restrictWidth, children, ...rest }) => ( +export const WithHeaderLayout: React.FC = ({ + restrictWidth, + restrictHeaderWidth, + children, + ...rest +}) => ( -
+
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/layout.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/layout.tsx index 73a7ba8ec119d9..39d882f7fdf65e 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/layout.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/layout.tsx @@ -18,16 +18,14 @@ import { import { WithHeaderLayout } from '../../../../layouts'; import { AgentConfig, PackageInfo } from '../../../../types'; import { PackageIcon } from '../../../../components/package_icon'; -import { CreateDatasourceFrom, CreateDatasourceStep } from '../types'; +import { CreateDatasourceFrom } from '../types'; export const CreateDatasourcePageLayout: React.FunctionComponent<{ from: CreateDatasourceFrom; - basePath: string; cancelUrl: string; - maxStep: CreateDatasourceStep | ''; agentConfig?: AgentConfig; packageInfo?: PackageInfo; -}> = ({ from, basePath, cancelUrl, maxStep, agentConfig, packageInfo, children }) => { +}> = ({ from, cancelUrl, agentConfig, packageInfo, children }) => { const leftColumn = ( diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/index.tsx index 1ad579d591b211..3c79fe17fdbb51 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/index.tsx @@ -28,12 +28,11 @@ import { } from '../../../hooks'; import { useLinks as useEPMLinks } from '../../epm/hooks'; import { CreateDatasourcePageLayout, ConfirmCreateDatasourceModal } from './components'; -import { CreateDatasourceFrom, CreateDatasourceStep } from './types'; +import { CreateDatasourceFrom } from './types'; import { DatasourceValidationResults, validateDatasource, validationHasErrors } from './services'; import { StepSelectPackage } from './step_select_package'; import { StepSelectConfig } from './step_select_config'; import { StepConfigureDatasource } from './step_configure_datasource'; - import { StepDefineDatasource } from './step_define_datasource'; export const CreateDatasourcePage: React.FunctionComponent = () => { @@ -43,11 +42,9 @@ export const CreateDatasourcePage: React.FunctionComponent = () => { } = useConfig(); const { params: { configId, pkgkey }, - url: basePath, } = useRouteMatch(); const history = useHistory(); const from: CreateDatasourceFrom = configId ? 'config' : 'package'; - const [maxStep, setMaxStep] = useState(''); // Agent config and package info states const [agentConfig, setAgentConfig] = useState(); @@ -91,7 +88,6 @@ export const CreateDatasourcePage: React.FunctionComponent = () => { } else { setFormState('INVALID'); setPackageInfo(undefined); - setMaxStep(''); } // eslint-disable-next-line no-console @@ -105,7 +101,6 @@ export const CreateDatasourcePage: React.FunctionComponent = () => { } else { setFormState('INVALID'); setAgentConfig(undefined); - setMaxStep(''); } // eslint-disable-next-line no-console @@ -189,9 +184,7 @@ export const CreateDatasourcePage: React.FunctionComponent = () => { const layoutProps = { from, - basePath, cancelUrl, - maxStep, agentConfig, packageInfo, }; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/types.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/types.ts index bd05be2d8a558d..85cc758fc4c464 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/types.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/types.ts @@ -5,4 +5,3 @@ */ export type CreateDatasourceFrom = 'package' | 'config'; -export type CreateDatasourceStep = 'selectConfig' | 'selectPackage' | 'configure' | 'review'; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/index.tsx index ea6b045f504ec1..05d150fd9ae231 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/index.tsx @@ -3,12 +3,71 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; -import { EuiText, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import React, { useState } from 'react'; +import styled from 'styled-components'; +import { + EuiButton, + EuiButtonEmpty, + EuiPanel, + EuiText, + EuiTitle, + EuiDescriptionList, + EuiDescriptionListDescription, + EuiDescriptionListTitle, + EuiFlexGrid, + EuiFlexGroup, + EuiFlexItem, +} from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { WithHeaderLayout } from '../../layouts'; +import { useLink, useGetAgentConfigs } from '../../hooks'; +import { AgentEnrollmentFlyout } from '../fleet/agent_list_page/components'; +import { EPM_PATH, FLEET_PATH, AGENT_CONFIG_PATH } from '../../constants'; + +const OverviewPanel = styled(EuiPanel).attrs(props => ({ + paddingSize: 'm', +}))` + header { + display: flex; + align-items: center; + justify-content: space-between; + border-bottom: 1px solid ${props => props.theme.eui.euiColorLightShade}; + margin: -${props => props.theme.eui.paddingSizes.m} -${props => props.theme.eui.paddingSizes.m} + ${props => props.theme.eui.paddingSizes.m}; + padding: ${props => props.theme.eui.paddingSizes.s} ${props => props.theme.eui.paddingSizes.m}; + } + + h2 { + padding: ${props => props.theme.eui.paddingSizes.xs} 0; + } +`; + +const OverviewStats = styled(EuiDescriptionList).attrs(props => ({ + compressed: true, + textStyle: 'reverse', + type: 'column', +}))` + & > * { + margin-top: ${props => props.theme.eui.paddingSizes.s} !important; + + &:first-child, + &:nth-child(2) { + margin-top: 0 !important; + } + } +`; export const IngestManagerOverview: React.FunctionComponent = () => { + // Agent enrollment flyout state + const [isEnrollmentFlyoutOpen, setIsEnrollmentFlyoutOpen] = useState(false); + + // Agent configs required for enrollment flyout + const agentConfigsRequest = useGetAgentConfigs({ + page: 1, + perPage: 1000, + }); + const agentConfigs = agentConfigsRequest.data ? agentConfigsRequest.data.items : []; + return ( {

} - /> + rightColumn={ + + + setIsEnrollmentFlyoutOpen(true)}> + + + + + } + > + {isEnrollmentFlyoutOpen && ( + setIsEnrollmentFlyoutOpen(false)} + /> + )} + + + + +
+ +

+ +

+
+ + + +
+ + Total available + 999 + Installed + 1 + Updated available + 0 + +
+
+ + + +
+ +

+ +

+
+ + + +
+ + Total configs + 1 + Data sources + 1 + +
+
+ + + +
+ +

+ +

+
+ + + +
+ + Total agents + 0 + Active + 0 + Offline + 0 + Error + 0 + +
+
+ + + +
+ +

+ +

+
+ + + +
+ + Data streams + 0 + Name spaces + 0 + Total size + 0 MB + +
+
+
+ ); }; diff --git a/x-pack/plugins/ingest_pipelines/public/application/constants/index.ts b/x-pack/plugins/ingest_pipelines/public/application/constants/index.ts index ae2b285c91c53f..ed4bd0a42d38ef 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/constants/index.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/constants/index.ts @@ -9,3 +9,5 @@ export const UIM_APP_NAME = 'ingest_pipelines'; export const UIM_PIPELINES_LIST_LOAD = 'pipelines_list_load'; export const UIM_PIPELINE_CREATE = 'pipeline_create'; export const UIM_PIPELINE_UPDATE = 'pipeline_update'; +export const UIM_PIPELINE_DELETE = 'pipeline_delete'; +export const UIM_PIPELINE_DELETE_MANY = 'pipeline_delete_many'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/index.tsx b/x-pack/plugins/ingest_pipelines/public/application/index.tsx index 2a70b1bfbf0f21..e43dba4689b443 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/index.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/index.tsx @@ -7,7 +7,7 @@ import { HttpSetup } from 'kibana/public'; import React, { ReactNode } from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; - +import { NotificationsSetup } from 'kibana/public'; import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public'; import { API_BASE_PATH } from '../../common/constants'; @@ -22,6 +22,7 @@ export interface AppServices { metric: UiMetricService; documentation: DocumentationService; api: ApiService; + notifications: NotificationsSetup; } export interface CoreServices { diff --git a/x-pack/plugins/ingest_pipelines/public/application/mount_management_section.ts b/x-pack/plugins/ingest_pipelines/public/application/mount_management_section.ts index 27b2f83046f866..baa5a569ac5e52 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/mount_management_section.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/mount_management_section.ts @@ -28,6 +28,7 @@ export async function mountManagementSection( metric: uiMetricService, documentation: documentationService, api: apiService, + notifications: coreSetup.notifications, }; return renderApp(element, I18nContext, services, { http }); diff --git a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/delete_modal.tsx b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/delete_modal.tsx new file mode 100644 index 00000000000000..c7736a6c19ba1e --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/delete_modal.tsx @@ -0,0 +1,125 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { EuiConfirmModal, EuiOverlayMask } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; + +import { useKibana } from '../../../shared_imports'; + +export const PipelineDeleteModal = ({ + pipelinesToDelete, + callback, +}: { + pipelinesToDelete: string[]; + callback: (data?: { hasDeletedPipelines: boolean }) => void; +}) => { + const { services } = useKibana(); + + const numPipelinesToDelete = pipelinesToDelete.length; + + const handleDeletePipelines = () => { + services.api + .deletePipelines(pipelinesToDelete) + .then(({ data: { itemsDeleted, errors }, error }) => { + const hasDeletedPipelines = itemsDeleted && itemsDeleted.length; + + if (hasDeletedPipelines) { + const successMessage = + itemsDeleted.length === 1 + ? i18n.translate( + 'xpack.ingestPipelines.deleteModal.successDeleteSingleNotificationMessageText', + { + defaultMessage: "Deleted pipeline '{pipelineName}'", + values: { pipelineName: pipelinesToDelete[0] }, + } + ) + : i18n.translate( + 'xpack.ingestPipelines.deleteModal.successDeleteMultipleNotificationMessageText', + { + defaultMessage: + 'Deleted {numSuccesses, plural, one {# pipeline} other {# pipelines}}', + values: { numSuccesses: itemsDeleted.length }, + } + ); + + callback({ hasDeletedPipelines }); + services.notifications.toasts.addSuccess(successMessage); + } + + if (error || errors?.length) { + const hasMultipleErrors = errors?.length > 1 || (error && pipelinesToDelete.length > 1); + const errorMessage = hasMultipleErrors + ? i18n.translate( + 'xpack.ingestPipelines.deleteModal.multipleErrorsNotificationMessageText', + { + defaultMessage: 'Error deleting {count} pipelines', + values: { + count: errors?.length || pipelinesToDelete.length, + }, + } + ) + : i18n.translate('xpack.ingestPipelines.deleteModal.errorNotificationMessageText', { + defaultMessage: "Error deleting pipeline '{name}'", + values: { name: (errors && errors[0].name) || pipelinesToDelete[0] }, + }); + services.notifications.toasts.addDanger(errorMessage); + } + }); + }; + + const handleOnCancel = () => { + callback(); + }; + + return ( + + + } + onCancel={handleOnCancel} + onConfirm={handleDeletePipelines} + cancelButtonText={ + + } + confirmButtonText={ + + } + > + <> +

+ +

+ +
    + {pipelinesToDelete.map(name => ( +
  • {name}
  • + ))} +
+ +
+
+ ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/details.tsx b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/details.tsx index 798b9153a16441..10720153cd57b8 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/details.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/details.tsx @@ -12,7 +12,8 @@ import { EuiFlyoutBody, EuiTitle, EuiDescriptionList, - EuiSpacer, + EuiDescriptionListTitle, + EuiDescriptionListDescription, EuiFlyoutFooter, EuiFlexGroup, EuiFlexItem, @@ -25,7 +26,7 @@ import { PipelineDetailsJsonBlock } from './details_json_block'; export interface Props { pipeline: Pipeline; onEditClick: (pipelineName: string) => void; - onDeleteClick: () => void; + onDeleteClick: (pipelineName: string[]) => void; onClose: () => void; } @@ -35,24 +36,6 @@ export const PipelineDetails: FunctionComponent = ({ onEditClick, onDeleteClick, }) => { - const descriptionListItems = [ - { - title: i18n.translate('xpack.ingestPipelines.list.pipelineDetails.descriptionTitle', { - defaultMessage: 'Description', - }), - description: pipeline.description ?? '', - }, - ]; - - if (pipeline.version) { - descriptionListItems.push({ - title: i18n.translate('xpack.ingestPipelines.list.pipelineDetails.versionTitle', { - defaultMessage: 'Version', - }), - description: String(pipeline.version), - }); - } - return ( = ({ - + + {/* Pipeline description */} + + {i18n.translate('xpack.ingestPipelines.list.pipelineDetails.descriptionTitle', { + defaultMessage: 'Description', + })} + + + {pipeline.description ?? ''} + - + {/* Pipeline version */} + {pipeline.version && ( + <> + + {i18n.translate('xpack.ingestPipelines.list.pipelineDetails.versionTitle', { + defaultMessage: 'Version', + })} + + + {String(pipeline.version)} + + + )} - + {/* Processors JSON */} + + {i18n.translate('xpack.ingestPipelines.list.pipelineDetails.processorsTitle', { + defaultMessage: 'Processors JSON', + })} + + + + - {/* On Failure Processor JSON */} - {pipeline.on_failure?.length && ( - <> - - - - )} - {/* End On Failure Processor JSON */} + {/* On Failure Processor JSON */} + {pipeline.on_failure?.length && ( + <> + + {i18n.translate( + 'xpack.ingestPipelines.list.pipelineDetails.failureProcessorsTitle', + { + defaultMessage: 'On failure processors JSON', + } + )} + + + + + + )} + @@ -116,7 +122,7 @@ export const PipelineDetails: FunctionComponent = ({ - + onDeleteClick([pipeline.name])}> {i18n.translate('xpack.ingestPipelines.list.pipelineDetails.deleteButtonLabel', { defaultMessage: 'Delete', })} diff --git a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/details_json_block.tsx b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/details_json_block.tsx index b648d2445b2717..6c44336c7547d4 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/details_json_block.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/details_json_block.tsx @@ -4,24 +4,28 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { FunctionComponent } from 'react'; -import { EuiCodeBlock, EuiText } from '@elastic/eui'; +import React, { FunctionComponent, useRef } from 'react'; +import { EuiCodeBlock } from '@elastic/eui'; export interface Props { - htmlForId: string; - label: string; json: Record; } -export const PipelineDetailsJsonBlock: FunctionComponent = ({ label, htmlForId, json }) => ( - <> - - - - +export const PipelineDetailsJsonBlock: FunctionComponent = ({ json }) => { + // Hack so copied-to-clipboard value updates as content changes + // Related issue: https://github.com/elastic/eui/issues/3321 + const uuid = useRef(0); + uuid.current++; + + return ( + 0 ? 300 : undefined} + isCopyable + key={uuid.current} + > {JSON.stringify(json, null, 2)} - -); + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/empty_list.tsx b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/empty_list.tsx index 45c09a944a74f8..ef64fb33a6a55d 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/empty_list.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/empty_list.tsx @@ -14,12 +14,12 @@ export const EmptyList: FunctionComponent = () => ( title={

{i18n.translate('xpack.ingestPipelines.list.table.emptyPromptTitle', { - defaultMessage: 'Create your first pipeline', + defaultMessage: 'Start by creating a pipeline', })}

} actions={ - + {i18n.translate('xpack.ingestPipelines.list.table.emptyPrompt.createButtonLabel', { defaultMessage: 'Create a pipeline', })} diff --git a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/main.tsx b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/main.tsx index 311c1c9d4c9e7e..ca4892fe281c28 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/main.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/main.tsx @@ -29,11 +29,13 @@ import { UIM_PIPELINES_LIST_LOAD } from '../../constants'; import { EmptyList } from './empty_list'; import { PipelineTable } from './table'; import { PipelineDetails } from './details'; +import { PipelineDeleteModal } from './delete_modal'; export const PipelinesList: React.FunctionComponent = ({ history }) => { const { services } = useKibana(); const [selectedPipeline, setSelectedPipeline] = useState(undefined); + const [pipelinesToDelete, setPipelinesToDelete] = useState([]); // Track component loaded useEffect(() => { @@ -63,7 +65,7 @@ export const PipelinesList: React.FunctionComponent = ({ hi {}} + onDeletePipelineClick={setPipelinesToDelete} onViewPipelineClick={setSelectedPipeline} pipelines={data} /> @@ -128,10 +130,23 @@ export const PipelinesList: React.FunctionComponent = ({ hi setSelectedPipeline(undefined)} - onDeleteClick={() => {}} + onDeleteClick={setPipelinesToDelete} onEditClick={editPipeline} /> )} + {pipelinesToDelete?.length > 0 ? ( + { + if (deleteResponse?.hasDeletedPipelines) { + // reload pipelines list + sendRequest(); + } + setPipelinesToDelete([]); + setSelectedPipeline(undefined); + }} + pipelinesToDelete={pipelinesToDelete} + /> + ) : null} ); }; diff --git a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/table.tsx b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/table.tsx index 45f539007cde3d..01b05eace3b60d 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/table.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/table.tsx @@ -3,8 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import React, { FunctionComponent } from 'react'; +import React, { FunctionComponent, useState } from 'react'; import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; import { EuiInMemoryTable, EuiLink, EuiButton } from '@elastic/eui'; import { BASE_PATH } from '../../../../common/constants'; @@ -13,8 +14,8 @@ import { Pipeline } from '../../../../common/types'; export interface Props { pipelines: Pipeline[]; onReloadClick: () => void; - onEditPipelineClick: (pipeineName: string) => void; - onDeletePipelineClick: (pipeline: Pipeline) => void; + onEditPipelineClick: (pipelineName: string) => void; + onDeletePipelineClick: (pipelineName: string[]) => void; onViewPipelineClick: (pipeline: Pipeline) => void; } @@ -25,9 +26,32 @@ export const PipelineTable: FunctionComponent = ({ onDeletePipelineClick, onViewPipelineClick, }) => { + const [selection, setSelection] = useState([]); + return ( 0 ? ( + onDeletePipelineClick(selection.map(pipeline => pipeline.name))} + color="danger" + > + + + ) : ( + undefined + ), toolsRight: [ = ({ name: i18n.translate('xpack.ingestPipelines.list.table.nameColumnTitle', { defaultMessage: 'Name', }), - render: (name: any, pipeline) => ( + render: (name: string, pipeline) => ( onViewPipelineClick(pipeline)}>{name} ), }, @@ -98,7 +122,7 @@ export const PipelineTable: FunctionComponent = ({ type: 'icon', icon: 'trash', color: 'danger', - onClick: onDeletePipelineClick, + onClick: ({ name }) => onDeletePipelineClick([name]), }, ], }, diff --git a/x-pack/plugins/ingest_pipelines/public/application/services/api.ts b/x-pack/plugins/ingest_pipelines/public/application/services/api.ts index 48b925b02eeb4d..42a157705baa7e 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/services/api.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/services/api.ts @@ -15,7 +15,12 @@ import { useRequest as _useRequest, } from '../../shared_imports'; import { UiMetricService } from './ui_metric'; -import { UIM_PIPELINE_CREATE, UIM_PIPELINE_UPDATE } from '../constants'; +import { + UIM_PIPELINE_CREATE, + UIM_PIPELINE_UPDATE, + UIM_PIPELINE_DELETE, + UIM_PIPELINE_DELETE_MANY, +} from '../constants'; export class ApiService { private client: HttpSetup | undefined; @@ -87,6 +92,17 @@ export class ApiService { return result; } + + public async deletePipelines(names: string[]) { + const result = this.sendRequest({ + path: `${API_BASE_PATH}/${names.map(name => encodeURIComponent(name)).join(',')}`, + method: 'delete', + }); + + this.trackUiMetric(names.length > 1 ? UIM_PIPELINE_DELETE_MANY : UIM_PIPELINE_DELETE); + + return result; + } } export const apiService = new ApiService(); diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/delete.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/delete.ts new file mode 100644 index 00000000000000..4664b49a08a501 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/delete.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { schema } from '@kbn/config-schema'; + +import { API_BASE_PATH } from '../../../common/constants'; +import { RouteDependencies } from '../../types'; + +const paramsSchema = schema.object({ + names: schema.string(), +}); + +export const registerDeleteRoute = ({ router, license }: RouteDependencies): void => { + router.delete( + { + path: `${API_BASE_PATH}/{names}`, + validate: { + params: paramsSchema, + }, + }, + license.guardApiRoute(async (ctx, req, res) => { + const { callAsCurrentUser } = ctx.core.elasticsearch.dataClient; + const { names } = req.params; + const pipelineNames = names.split(','); + + const response: { itemsDeleted: string[]; errors: any[] } = { + itemsDeleted: [], + errors: [], + }; + + await Promise.all( + pipelineNames.map(pipelineName => { + return callAsCurrentUser('ingest.deletePipeline', { id: pipelineName }) + .then(() => response.itemsDeleted.push(pipelineName)) + .catch(e => + response.errors.push({ + name: pipelineName, + error: e, + }) + ); + }) + ); + + return res.ok({ body: response }); + }) + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/index.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/index.ts index 98be8d660c874c..37819b9bf68899 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/index.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/index.ts @@ -11,3 +11,5 @@ export { registerCreateRoute } from './create'; export { registerUpdateRoute } from './update'; export { registerPrivilegesRoute } from './privileges'; + +export { registerDeleteRoute } from './delete'; diff --git a/x-pack/plugins/ingest_pipelines/server/routes/index.ts b/x-pack/plugins/ingest_pipelines/server/routes/index.ts index 1bc62efeb14d85..8cfcc1054ca4ed 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/index.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/index.ts @@ -11,6 +11,7 @@ import { registerCreateRoute, registerUpdateRoute, registerPrivilegesRoute, + registerDeleteRoute, } from './api'; export class ApiRoutes { @@ -19,5 +20,6 @@ export class ApiRoutes { registerCreateRoute(dependencies); registerUpdateRoute(dependencies); registerPrivilegesRoute(dependencies); + registerDeleteRoute(dependencies); } } diff --git a/x-pack/legacy/plugins/maps/common/migrations/add_field_meta_options.js b/x-pack/plugins/maps/common/migrations/add_field_meta_options.js similarity index 100% rename from x-pack/legacy/plugins/maps/common/migrations/add_field_meta_options.js rename to x-pack/plugins/maps/common/migrations/add_field_meta_options.js diff --git a/x-pack/legacy/plugins/maps/common/migrations/add_field_meta_options.test.js b/x-pack/plugins/maps/common/migrations/add_field_meta_options.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/common/migrations/add_field_meta_options.test.js rename to x-pack/plugins/maps/common/migrations/add_field_meta_options.test.js diff --git a/x-pack/legacy/plugins/maps/common/migrations/ems_raster_tile_to_ems_vector_tile.js b/x-pack/plugins/maps/common/migrations/ems_raster_tile_to_ems_vector_tile.js similarity index 100% rename from x-pack/legacy/plugins/maps/common/migrations/ems_raster_tile_to_ems_vector_tile.js rename to x-pack/plugins/maps/common/migrations/ems_raster_tile_to_ems_vector_tile.js diff --git a/x-pack/legacy/plugins/maps/common/migrations/ems_raster_tile_to_ems_vector_tile.test.js b/x-pack/plugins/maps/common/migrations/ems_raster_tile_to_ems_vector_tile.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/common/migrations/ems_raster_tile_to_ems_vector_tile.test.js rename to x-pack/plugins/maps/common/migrations/ems_raster_tile_to_ems_vector_tile.test.js diff --git a/x-pack/legacy/plugins/maps/common/migrations/join_agg_key.test.ts b/x-pack/plugins/maps/common/migrations/join_agg_key.test.ts similarity index 100% rename from x-pack/legacy/plugins/maps/common/migrations/join_agg_key.test.ts rename to x-pack/plugins/maps/common/migrations/join_agg_key.test.ts diff --git a/x-pack/legacy/plugins/maps/common/migrations/join_agg_key.ts b/x-pack/plugins/maps/common/migrations/join_agg_key.ts similarity index 97% rename from x-pack/legacy/plugins/maps/common/migrations/join_agg_key.ts rename to x-pack/plugins/maps/common/migrations/join_agg_key.ts index 29661aedb550c5..97b9ee4692c253 100644 --- a/x-pack/legacy/plugins/maps/common/migrations/join_agg_key.ts +++ b/x-pack/plugins/maps/common/migrations/join_agg_key.ts @@ -20,7 +20,7 @@ import { LayerDescriptor, VectorLayerDescriptor, } from '../descriptor_types'; -import { MapSavedObjectAttributes } from '../../../../../plugins/maps/common/map_saved_object_type'; +import { MapSavedObjectAttributes } from '../map_saved_object_type'; const GROUP_BY_DELIMITER = '_groupby_'; diff --git a/x-pack/legacy/plugins/maps/common/migrations/migrate_symbol_style_descriptor.js b/x-pack/plugins/maps/common/migrations/migrate_symbol_style_descriptor.js similarity index 100% rename from x-pack/legacy/plugins/maps/common/migrations/migrate_symbol_style_descriptor.js rename to x-pack/plugins/maps/common/migrations/migrate_symbol_style_descriptor.js diff --git a/x-pack/legacy/plugins/maps/common/migrations/migrate_symbol_style_descriptor.test.js b/x-pack/plugins/maps/common/migrations/migrate_symbol_style_descriptor.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/common/migrations/migrate_symbol_style_descriptor.test.js rename to x-pack/plugins/maps/common/migrations/migrate_symbol_style_descriptor.test.js diff --git a/x-pack/legacy/plugins/maps/common/migrations/move_apply_global_query.js b/x-pack/plugins/maps/common/migrations/move_apply_global_query.js similarity index 100% rename from x-pack/legacy/plugins/maps/common/migrations/move_apply_global_query.js rename to x-pack/plugins/maps/common/migrations/move_apply_global_query.js diff --git a/x-pack/legacy/plugins/maps/common/migrations/move_apply_global_query.test.js b/x-pack/plugins/maps/common/migrations/move_apply_global_query.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/common/migrations/move_apply_global_query.test.js rename to x-pack/plugins/maps/common/migrations/move_apply_global_query.test.js diff --git a/x-pack/legacy/plugins/maps/common/migrations/references.js b/x-pack/plugins/maps/common/migrations/references.js similarity index 100% rename from x-pack/legacy/plugins/maps/common/migrations/references.js rename to x-pack/plugins/maps/common/migrations/references.js diff --git a/x-pack/legacy/plugins/maps/common/migrations/references.test.js b/x-pack/plugins/maps/common/migrations/references.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/common/migrations/references.test.js rename to x-pack/plugins/maps/common/migrations/references.test.js diff --git a/x-pack/legacy/plugins/maps/common/migrations/scaling_type.test.ts b/x-pack/plugins/maps/common/migrations/scaling_type.test.ts similarity index 100% rename from x-pack/legacy/plugins/maps/common/migrations/scaling_type.test.ts rename to x-pack/plugins/maps/common/migrations/scaling_type.test.ts diff --git a/x-pack/legacy/plugins/maps/common/migrations/scaling_type.ts b/x-pack/plugins/maps/common/migrations/scaling_type.ts similarity index 93% rename from x-pack/legacy/plugins/maps/common/migrations/scaling_type.ts rename to x-pack/plugins/maps/common/migrations/scaling_type.ts index 551975fbacea52..98a06a764f4ec4 100644 --- a/x-pack/legacy/plugins/maps/common/migrations/scaling_type.ts +++ b/x-pack/plugins/maps/common/migrations/scaling_type.ts @@ -7,7 +7,7 @@ import _ from 'lodash'; import { SOURCE_TYPES, SCALING_TYPES } from '../constants'; import { LayerDescriptor, ESSearchSourceDescriptor } from '../descriptor_types'; -import { MapSavedObjectAttributes } from '../../../../../plugins/maps/common/map_saved_object_type'; +import { MapSavedObjectAttributes } from '../map_saved_object_type'; function isEsDocumentSource(layerDescriptor: LayerDescriptor) { const sourceType = _.get(layerDescriptor, 'sourceDescriptor.type'); diff --git a/x-pack/legacy/plugins/maps/common/migrations/top_hits_time_to_sort.js b/x-pack/plugins/maps/common/migrations/top_hits_time_to_sort.js similarity index 100% rename from x-pack/legacy/plugins/maps/common/migrations/top_hits_time_to_sort.js rename to x-pack/plugins/maps/common/migrations/top_hits_time_to_sort.js diff --git a/x-pack/legacy/plugins/maps/common/migrations/top_hits_time_to_sort.test.js b/x-pack/plugins/maps/common/migrations/top_hits_time_to_sort.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/common/migrations/top_hits_time_to_sort.test.js rename to x-pack/plugins/maps/common/migrations/top_hits_time_to_sort.test.js diff --git a/x-pack/plugins/maps/kibana.json b/x-pack/plugins/maps/kibana.json index b2aec30c113eb6..00c5e70ad6b8de 100644 --- a/x-pack/plugins/maps/kibana.json +++ b/x-pack/plugins/maps/kibana.json @@ -3,6 +3,14 @@ "version": "8.0.0", "kibanaVersion": "kibana", "configPath": ["xpack", "maps"], - "requiredPlugins": ["inspector"], + "requiredPlugins": [ + "inspector", + "home", + "data", + "fileUpload", + "uiActions", + "navigation", + "visualizations" + ], "ui": true } diff --git a/x-pack/legacy/plugins/maps/public/_main.scss b/x-pack/plugins/maps/public/_main.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/_main.scss rename to x-pack/plugins/maps/public/_main.scss diff --git a/x-pack/legacy/plugins/maps/public/_mapbox_hacks.scss b/x-pack/plugins/maps/public/_mapbox_hacks.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/_mapbox_hacks.scss rename to x-pack/plugins/maps/public/_mapbox_hacks.scss diff --git a/x-pack/plugins/maps/public/actions/map_actions.js b/x-pack/plugins/maps/public/actions/map_actions.js index 13cb3d5f898601..572385d628b16a 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.js +++ b/x-pack/plugins/maps/public/actions/map_actions.js @@ -4,6 +4,37 @@ * you may not use this file except in compliance with the Elastic License. */ +import _ from 'lodash'; +import turf from 'turf'; +import turfBooleanContains from '@turf/boolean-contains'; +import uuid from 'uuid/v4'; +import { + getLayerList, + getLayerListRaw, + getDataFilters, + getSelectedLayerId, + getMapReady, + getWaitingForMapReadyLayerListRaw, + getTransientLayerId, + getOpenTooltips, + getQuery, + getDataRequestDescriptor, +} from '../selectors/map_selectors'; + +import { FLYOUT_STATE } from '../reducers/ui'; +import { + cancelRequest, + registerCancelCallback, + unregisterCancelCallback, + getEventHandlers, +} from '../reducers/non_serializable_instances'; +import { updateFlyout } from './ui_actions'; +import { + FEATURE_ID_PROPERTY_NAME, + LAYER_TYPE, + SOURCE_DATA_ID_ORIGIN, +} from '../../common/constants'; + export const SET_SELECTED_LAYER = 'SET_SELECTED_LAYER'; export const SET_TRANSIENT_LAYER = 'SET_TRANSIENT_LAYER'; export const UPDATE_LAYER_ORDER = 'UPDATE_LAYER_ORDER'; @@ -45,3 +76,897 @@ export const HIDE_TOOLBAR_OVERLAY = 'HIDE_TOOLBAR_OVERLAY'; export const HIDE_LAYER_CONTROL = 'HIDE_LAYER_CONTROL'; export const HIDE_VIEW_CONTROL = 'HIDE_VIEW_CONTROL'; export const SET_WAITING_FOR_READY_HIDDEN_LAYERS = 'SET_WAITING_FOR_READY_HIDDEN_LAYERS'; + +function getLayerLoadingCallbacks(dispatch, getState, layerId) { + return { + startLoading: (dataId, requestToken, meta) => + dispatch(startDataLoad(layerId, dataId, requestToken, meta)), + stopLoading: (dataId, requestToken, data, meta) => + dispatch(endDataLoad(layerId, dataId, requestToken, data, meta)), + onLoadError: (dataId, requestToken, errorMessage) => + dispatch(onDataLoadError(layerId, dataId, requestToken, errorMessage)), + updateSourceData: newData => { + dispatch(updateSourceDataRequest(layerId, newData)); + }, + isRequestStillActive: (dataId, requestToken) => { + const dataRequest = getDataRequestDescriptor(getState(), layerId, dataId); + if (!dataRequest) { + return false; + } + return dataRequest.dataRequestToken === requestToken; + }, + registerCancelCallback: (requestToken, callback) => + dispatch(registerCancelCallback(requestToken, callback)), + }; +} + +function getLayerById(layerId, state) { + return getLayerList(state).find(layer => { + return layerId === layer.getId(); + }); +} + +async function syncDataForAllLayers(dispatch, getState, dataFilters) { + const state = getState(); + const layerList = getLayerList(state); + const syncs = layerList.map(layer => { + const loadingFunctions = getLayerLoadingCallbacks(dispatch, getState, layer.getId()); + return layer.syncData({ ...loadingFunctions, dataFilters }); + }); + await Promise.all(syncs); +} + +export function cancelAllInFlightRequests() { + return (dispatch, getState) => { + getLayerList(getState()).forEach(layer => { + dispatch(clearDataRequests(layer)); + }); + }; +} + +function clearDataRequests(layer) { + return dispatch => { + layer.getInFlightRequestTokens().forEach(requestToken => { + dispatch(cancelRequest(requestToken)); + }); + dispatch({ + type: UPDATE_LAYER_PROP, + id: layer.getId(), + propName: '__dataRequests', + newValue: [], + }); + }; +} + +export function setMapInitError(errorMessage) { + return { + type: SET_MAP_INIT_ERROR, + errorMessage, + }; +} + +export function trackCurrentLayerState(layerId) { + return { + type: TRACK_CURRENT_LAYER_STATE, + layerId: layerId, + }; +} + +export function rollbackToTrackedLayerStateForSelectedLayer() { + return async (dispatch, getState) => { + const layerId = getSelectedLayerId(getState()); + await dispatch({ + type: ROLLBACK_TO_TRACKED_LAYER_STATE, + layerId: layerId, + }); + + // Ensure updateStyleMeta is triggered + // syncDataForLayer may not trigger endDataLoad if no re-fetch is required + dispatch(updateStyleMeta(layerId)); + + dispatch(syncDataForLayer(layerId)); + }; +} + +export function removeTrackedLayerStateForSelectedLayer() { + return (dispatch, getState) => { + const layerId = getSelectedLayerId(getState()); + dispatch({ + type: REMOVE_TRACKED_LAYER_STATE, + layerId: layerId, + }); + }; +} + +export function replaceLayerList(newLayerList) { + return (dispatch, getState) => { + const isMapReady = getMapReady(getState()); + if (!isMapReady) { + dispatch({ + type: CLEAR_WAITING_FOR_MAP_READY_LAYER_LIST, + }); + } else { + getLayerListRaw(getState()).forEach(({ id }) => { + dispatch(removeLayerFromLayerList(id)); + }); + } + + newLayerList.forEach(layerDescriptor => { + dispatch(addLayer(layerDescriptor)); + }); + }; +} + +export function cloneLayer(layerId) { + return async (dispatch, getState) => { + const layer = getLayerById(layerId, getState()); + if (!layer) { + return; + } + + const clonedDescriptor = await layer.cloneDescriptor(); + dispatch(addLayer(clonedDescriptor)); + }; +} + +export function addLayer(layerDescriptor) { + return (dispatch, getState) => { + const isMapReady = getMapReady(getState()); + if (!isMapReady) { + dispatch({ + type: ADD_WAITING_FOR_MAP_READY_LAYER, + layer: layerDescriptor, + }); + return; + } + + dispatch({ + type: ADD_LAYER, + layer: layerDescriptor, + }); + dispatch(syncDataForLayer(layerDescriptor.id)); + }; +} + +// Do not use when rendering a map. Method exists to enable selectors for getLayerList when +// rendering is not needed. +export function addLayerWithoutDataSync(layerDescriptor) { + return { + type: ADD_LAYER, + layer: layerDescriptor, + }; +} + +function setLayerDataLoadErrorStatus(layerId, errorMessage) { + return dispatch => { + dispatch({ + type: SET_LAYER_ERROR_STATUS, + isInErrorState: errorMessage !== null, + layerId, + errorMessage, + }); + }; +} + +export function cleanTooltipStateForLayer(layerId, layerFeatures = []) { + return (dispatch, getState) => { + let featuresRemoved = false; + const openTooltips = getOpenTooltips(getState()) + .map(tooltipState => { + const nextFeatures = tooltipState.features.filter(tooltipFeature => { + if (tooltipFeature.layerId !== layerId) { + // feature from another layer, keep it + return true; + } + + // Keep feature if it is still in layer + return layerFeatures.some(layerFeature => { + return layerFeature.properties[FEATURE_ID_PROPERTY_NAME] === tooltipFeature.id; + }); + }); + + if (tooltipState.features.length !== nextFeatures.length) { + featuresRemoved = true; + } + + return { ...tooltipState, features: nextFeatures }; + }) + .filter(tooltipState => { + return tooltipState.features.length > 0; + }); + + if (featuresRemoved) { + dispatch({ + type: SET_OPEN_TOOLTIPS, + openTooltips, + }); + } + }; +} + +export function setLayerVisibility(layerId, makeVisible) { + return async (dispatch, getState) => { + //if the current-state is invisible, we also want to sync data + //e.g. if a layer was invisible at start-up, it won't have any data loaded + const layer = getLayerById(layerId, getState()); + + // If the layer visibility is already what we want it to be, do nothing + if (!layer || layer.isVisible() === makeVisible) { + return; + } + + if (!makeVisible) { + dispatch(cleanTooltipStateForLayer(layerId)); + } + + await dispatch({ + type: SET_LAYER_VISIBILITY, + layerId, + visibility: makeVisible, + }); + if (makeVisible) { + dispatch(syncDataForLayer(layerId)); + } + }; +} + +export function toggleLayerVisible(layerId) { + return async (dispatch, getState) => { + const layer = getLayerById(layerId, getState()); + if (!layer) { + return; + } + const makeVisible = !layer.isVisible(); + + dispatch(setLayerVisibility(layerId, makeVisible)); + }; +} + +export function setSelectedLayer(layerId) { + return async (dispatch, getState) => { + const oldSelectedLayer = getSelectedLayerId(getState()); + if (oldSelectedLayer) { + await dispatch(rollbackToTrackedLayerStateForSelectedLayer()); + } + if (layerId) { + dispatch(trackCurrentLayerState(layerId)); + } + dispatch({ + type: SET_SELECTED_LAYER, + selectedLayerId: layerId, + }); + }; +} + +export function removeTransientLayer() { + return async (dispatch, getState) => { + const transientLayerId = getTransientLayerId(getState()); + if (transientLayerId) { + await dispatch(removeLayerFromLayerList(transientLayerId)); + await dispatch(setTransientLayer(null)); + } + }; +} + +export function setTransientLayer(layerId) { + return { + type: SET_TRANSIENT_LAYER, + transientLayerId: layerId, + }; +} + +export function clearTransientLayerStateAndCloseFlyout() { + return async dispatch => { + await dispatch(updateFlyout(FLYOUT_STATE.NONE)); + await dispatch(setSelectedLayer(null)); + await dispatch(removeTransientLayer()); + }; +} + +export function updateLayerOrder(newLayerOrder) { + return { + type: UPDATE_LAYER_ORDER, + newLayerOrder, + }; +} + +export function mapReady() { + return (dispatch, getState) => { + dispatch({ + type: MAP_READY, + }); + + getWaitingForMapReadyLayerListRaw(getState()).forEach(layerDescriptor => { + dispatch(addLayer(layerDescriptor)); + }); + + dispatch({ + type: CLEAR_WAITING_FOR_MAP_READY_LAYER_LIST, + }); + }; +} + +export function mapDestroyed() { + return { + type: MAP_DESTROYED, + }; +} + +export function mapExtentChanged(newMapConstants) { + return async (dispatch, getState) => { + const state = getState(); + const dataFilters = getDataFilters(state); + const { extent, zoom: newZoom } = newMapConstants; + const { buffer, zoom: currentZoom } = dataFilters; + + if (extent) { + let doesBufferContainExtent = false; + if (buffer) { + const bufferGeometry = turf.bboxPolygon([ + buffer.minLon, + buffer.minLat, + buffer.maxLon, + buffer.maxLat, + ]); + const extentGeometry = turf.bboxPolygon([ + extent.minLon, + extent.minLat, + extent.maxLon, + extent.maxLat, + ]); + + doesBufferContainExtent = turfBooleanContains(bufferGeometry, extentGeometry); + } + + if (!doesBufferContainExtent || currentZoom !== newZoom) { + const scaleFactor = 0.5; // TODO put scale factor in store and fetch with selector + const width = extent.maxLon - extent.minLon; + const height = extent.maxLat - extent.minLat; + dataFilters.buffer = { + minLon: extent.minLon - width * scaleFactor, + minLat: extent.minLat - height * scaleFactor, + maxLon: extent.maxLon + width * scaleFactor, + maxLat: extent.maxLat + height * scaleFactor, + }; + } + } + + dispatch({ + type: MAP_EXTENT_CHANGED, + mapState: { + ...dataFilters, + ...newMapConstants, + }, + }); + const newDataFilters = { ...dataFilters, ...newMapConstants }; + await syncDataForAllLayers(dispatch, getState, newDataFilters); + }; +} + +export function closeOnClickTooltip(tooltipId) { + return (dispatch, getState) => { + dispatch({ + type: SET_OPEN_TOOLTIPS, + openTooltips: getOpenTooltips(getState()).filter(({ id }) => { + return tooltipId !== id; + }), + }); + }; +} + +export function openOnClickTooltip(tooltipState) { + return (dispatch, getState) => { + const openTooltips = getOpenTooltips(getState()).filter(({ features, location, isLocked }) => { + return ( + isLocked && + !_.isEqual(location, tooltipState.location) && + !_.isEqual(features, tooltipState.features) + ); + }); + + openTooltips.push({ + ...tooltipState, + isLocked: true, + id: uuid(), + }); + + dispatch({ + type: SET_OPEN_TOOLTIPS, + openTooltips, + }); + }; +} + +export function closeOnHoverTooltip() { + return (dispatch, getState) => { + if (getOpenTooltips(getState()).length) { + dispatch({ + type: SET_OPEN_TOOLTIPS, + openTooltips: [], + }); + } + }; +} + +export function openOnHoverTooltip(tooltipState) { + return { + type: SET_OPEN_TOOLTIPS, + openTooltips: [ + { + ...tooltipState, + isLocked: false, + id: uuid(), + }, + ], + }; +} + +export function setMouseCoordinates({ lat, lon }) { + let safeLon = lon; + if (lon > 180) { + const overlapWestOfDateLine = lon - 180; + safeLon = -180 + overlapWestOfDateLine; + } else if (lon < -180) { + const overlapEastOfDateLine = Math.abs(lon) - 180; + safeLon = 180 - overlapEastOfDateLine; + } + + return { + type: SET_MOUSE_COORDINATES, + lat, + lon: safeLon, + }; +} + +export function clearMouseCoordinates() { + return { type: CLEAR_MOUSE_COORDINATES }; +} + +export function disableScrollZoom() { + return { type: SET_SCROLL_ZOOM, scrollZoom: false }; +} + +export function fitToLayerExtent(layerId) { + return async function(dispatch, getState) { + const targetLayer = getLayerById(layerId, getState()); + + if (targetLayer) { + const dataFilters = getDataFilters(getState()); + const bounds = await targetLayer.getBounds(dataFilters); + if (bounds) { + await dispatch(setGotoWithBounds(bounds)); + } + } + }; +} + +export function setGotoWithBounds(bounds) { + return { + type: SET_GOTO, + bounds: bounds, + }; +} + +export function setGotoWithCenter({ lat, lon, zoom }) { + return { + type: SET_GOTO, + center: { lat, lon, zoom }, + }; +} + +export function clearGoto() { + return { type: CLEAR_GOTO }; +} + +export function startDataLoad(layerId, dataId, requestToken, meta = {}) { + return (dispatch, getState) => { + const layer = getLayerById(layerId, getState()); + if (layer) { + dispatch(cancelRequest(layer.getPrevRequestToken(dataId))); + } + + const eventHandlers = getEventHandlers(getState()); + if (eventHandlers && eventHandlers.onDataLoad) { + eventHandlers.onDataLoad({ + layerId, + dataId, + }); + } + + dispatch({ + meta, + type: LAYER_DATA_LOAD_STARTED, + layerId, + dataId, + requestToken, + }); + }; +} + +export function updateSourceDataRequest(layerId, newData) { + return dispatch => { + dispatch({ + type: UPDATE_SOURCE_DATA_REQUEST, + dataId: SOURCE_DATA_ID_ORIGIN, + layerId, + newData, + }); + + dispatch(updateStyleMeta(layerId)); + }; +} + +export function endDataLoad(layerId, dataId, requestToken, data, meta) { + return async (dispatch, getState) => { + dispatch(unregisterCancelCallback(requestToken)); + + const features = data && data.features ? data.features : []; + + const eventHandlers = getEventHandlers(getState()); + if (eventHandlers && eventHandlers.onDataLoadEnd) { + const layer = getLayerById(layerId, getState()); + const resultMeta = {}; + if (layer && layer.getType() === LAYER_TYPE.VECTOR) { + resultMeta.featuresCount = features.length; + } + + eventHandlers.onDataLoadEnd({ + layerId, + dataId, + resultMeta, + }); + } + + dispatch(cleanTooltipStateForLayer(layerId, features)); + dispatch({ + type: LAYER_DATA_LOAD_ENDED, + layerId, + dataId, + data, + meta, + requestToken, + }); + + //Clear any data-load errors when there is a succesful data return. + //Co this on end-data-load iso at start-data-load to avoid blipping the error status between true/false. + //This avoids jitter in the warning icon of the TOC when the requests continues to return errors. + dispatch(setLayerDataLoadErrorStatus(layerId, null)); + + dispatch(updateStyleMeta(layerId)); + }; +} + +export function onDataLoadError(layerId, dataId, requestToken, errorMessage) { + return async (dispatch, getState) => { + dispatch(unregisterCancelCallback(requestToken)); + + const eventHandlers = getEventHandlers(getState()); + if (eventHandlers && eventHandlers.onDataLoadError) { + eventHandlers.onDataLoadError({ + layerId, + dataId, + errorMessage, + }); + } + + dispatch(cleanTooltipStateForLayer(layerId)); + dispatch({ + type: LAYER_DATA_LOAD_ERROR, + data: null, + layerId, + dataId, + requestToken, + }); + + dispatch(setLayerDataLoadErrorStatus(layerId, errorMessage)); + }; +} + +export function updateSourceProp(layerId, propName, value, newLayerType) { + return async dispatch => { + dispatch({ + type: UPDATE_SOURCE_PROP, + layerId, + propName, + value, + }); + if (newLayerType) { + dispatch(updateLayerType(layerId, newLayerType)); + } + await dispatch(clearMissingStyleProperties(layerId)); + dispatch(syncDataForLayer(layerId)); + }; +} + +function updateLayerType(layerId, newLayerType) { + return (dispatch, getState) => { + const layer = getLayerById(layerId, getState()); + if (!layer || layer.getType() === newLayerType) { + return; + } + dispatch(clearDataRequests(layer)); + dispatch({ + type: UPDATE_LAYER_PROP, + id: layerId, + propName: 'type', + newValue: newLayerType, + }); + }; +} + +export function syncDataForLayer(layerId) { + return async (dispatch, getState) => { + const targetLayer = getLayerById(layerId, getState()); + if (targetLayer) { + const dataFilters = getDataFilters(getState()); + const loadingFunctions = getLayerLoadingCallbacks(dispatch, getState, layerId); + await targetLayer.syncData({ + ...loadingFunctions, + dataFilters, + }); + } + }; +} + +export function updateLayerLabel(id, newLabel) { + return { + type: UPDATE_LAYER_PROP, + id, + propName: 'label', + newValue: newLabel, + }; +} + +export function updateLayerMinZoom(id, minZoom) { + return { + type: UPDATE_LAYER_PROP, + id, + propName: 'minZoom', + newValue: minZoom, + }; +} + +export function updateLayerMaxZoom(id, maxZoom) { + return { + type: UPDATE_LAYER_PROP, + id, + propName: 'maxZoom', + newValue: maxZoom, + }; +} + +export function updateLayerAlpha(id, alpha) { + return { + type: UPDATE_LAYER_PROP, + id, + propName: 'alpha', + newValue: alpha, + }; +} + +export function setLayerQuery(id, query) { + return dispatch => { + dispatch({ + type: UPDATE_LAYER_PROP, + id, + propName: 'query', + newValue: query, + }); + + dispatch(syncDataForLayer(id)); + }; +} + +export function removeSelectedLayer() { + return (dispatch, getState) => { + const state = getState(); + const layerId = getSelectedLayerId(state); + dispatch(removeLayer(layerId)); + }; +} + +export function removeLayer(layerId) { + return async (dispatch, getState) => { + const state = getState(); + const selectedLayerId = getSelectedLayerId(state); + if (layerId === selectedLayerId) { + dispatch(updateFlyout(FLYOUT_STATE.NONE)); + await dispatch(setSelectedLayer(null)); + } + dispatch(removeLayerFromLayerList(layerId)); + }; +} + +function removeLayerFromLayerList(layerId) { + return (dispatch, getState) => { + const layerGettingRemoved = getLayerById(layerId, getState()); + if (!layerGettingRemoved) { + return; + } + + layerGettingRemoved.getInFlightRequestTokens().forEach(requestToken => { + dispatch(cancelRequest(requestToken)); + }); + dispatch(cleanTooltipStateForLayer(layerId)); + layerGettingRemoved.destroy(); + dispatch({ + type: REMOVE_LAYER, + id: layerId, + }); + }; +} + +export function setQuery({ query, timeFilters, filters = [], refresh = false }) { + function generateQueryTimestamp() { + return new Date().toISOString(); + } + return async (dispatch, getState) => { + const prevQuery = getQuery(getState()); + const prevTriggeredAt = + prevQuery && prevQuery.queryLastTriggeredAt + ? prevQuery.queryLastTriggeredAt + : generateQueryTimestamp(); + + dispatch({ + type: SET_QUERY, + timeFilters, + query: { + ...query, + // ensure query changes to trigger re-fetch when "Refresh" clicked + queryLastTriggeredAt: refresh ? generateQueryTimestamp() : prevTriggeredAt, + }, + filters, + }); + + const dataFilters = getDataFilters(getState()); + await syncDataForAllLayers(dispatch, getState, dataFilters); + }; +} + +export function setRefreshConfig({ isPaused, interval }) { + return { + type: SET_REFRESH_CONFIG, + isPaused, + interval, + }; +} + +export function triggerRefreshTimer() { + return async (dispatch, getState) => { + dispatch({ + type: TRIGGER_REFRESH_TIMER, + }); + + const dataFilters = getDataFilters(getState()); + await syncDataForAllLayers(dispatch, getState, dataFilters); + }; +} + +export function clearMissingStyleProperties(layerId) { + return async (dispatch, getState) => { + const targetLayer = getLayerById(layerId, getState()); + if (!targetLayer) { + return; + } + + const style = targetLayer.getCurrentStyle(); + if (!style) { + return; + } + + const nextFields = await targetLayer.getFields(); //take into account all fields, since labels can be driven by any field (source or join) + const { hasChanges, nextStyleDescriptor } = style.getDescriptorWithMissingStylePropsRemoved( + nextFields + ); + if (hasChanges) { + dispatch(updateLayerStyle(layerId, nextStyleDescriptor)); + } + }; +} + +export function updateLayerStyle(layerId, styleDescriptor) { + return dispatch => { + dispatch({ + type: UPDATE_LAYER_STYLE, + layerId, + style: { + ...styleDescriptor, + }, + }); + + // Ensure updateStyleMeta is triggered + // syncDataForLayer may not trigger endDataLoad if no re-fetch is required + dispatch(updateStyleMeta(layerId)); + + // Style update may require re-fetch, for example ES search may need to retrieve field used for dynamic styling + dispatch(syncDataForLayer(layerId)); + }; +} + +export function updateStyleMeta(layerId) { + return async (dispatch, getState) => { + const layer = getLayerById(layerId, getState()); + if (!layer) { + return; + } + const sourceDataRequest = layer.getSourceDataRequest(); + const style = layer.getCurrentStyle(); + if (!style || !sourceDataRequest) { + return; + } + const styleMeta = await style.pluckStyleMetaFromSourceDataRequest(sourceDataRequest); + dispatch({ + type: SET_LAYER_STYLE_META, + layerId, + styleMeta, + }); + }; +} + +export function updateLayerStyleForSelectedLayer(styleDescriptor) { + return (dispatch, getState) => { + const selectedLayerId = getSelectedLayerId(getState()); + if (!selectedLayerId) { + return; + } + dispatch(updateLayerStyle(selectedLayerId, styleDescriptor)); + }; +} + +export function setJoinsForLayer(layer, joins) { + return async dispatch => { + await dispatch({ + type: SET_JOINS, + layer: layer, + joins: joins, + }); + + await dispatch(clearMissingStyleProperties(layer.getId())); + dispatch(syncDataForLayer(layer.getId())); + }; +} + +export function updateDrawState(drawState) { + return dispatch => { + if (drawState !== null) { + dispatch({ type: SET_OPEN_TOOLTIPS, openTooltips: [] }); // tooltips just get in the way + } + dispatch({ + type: UPDATE_DRAW_STATE, + drawState: drawState, + }); + }; +} + +export function disableInteractive() { + return { type: SET_INTERACTIVE, disableInteractive: true }; +} + +export function disableTooltipControl() { + return { type: DISABLE_TOOLTIP_CONTROL, disableTooltipControl: true }; +} + +export function hideToolbarOverlay() { + return { type: HIDE_TOOLBAR_OVERLAY, hideToolbarOverlay: true }; +} + +export function hideLayerControl() { + return { type: HIDE_LAYER_CONTROL, hideLayerControl: true }; +} +export function hideViewControl() { + return { type: HIDE_VIEW_CONTROL, hideViewControl: true }; +} + +export function setHiddenLayers(hiddenLayerIds) { + return (dispatch, getState) => { + const isMapReady = getMapReady(getState()); + + if (!isMapReady) { + dispatch({ type: SET_WAITING_FOR_READY_HIDDEN_LAYERS, hiddenLayerIds }); + } else { + getLayerListRaw(getState()).forEach(layer => + dispatch(setLayerVisibility(layer.id, !hiddenLayerIds.includes(layer.id))) + ); + } + }; +} diff --git a/x-pack/legacy/plugins/maps/public/actions/map_actions.test.js b/x-pack/plugins/maps/public/actions/map_actions.test.js similarity index 98% rename from x-pack/legacy/plugins/maps/public/actions/map_actions.test.js rename to x-pack/plugins/maps/public/actions/map_actions.test.js index 7e2a3c827fa88f..c280b8af7ab80d 100644 --- a/x-pack/legacy/plugins/maps/public/actions/map_actions.test.js +++ b/x-pack/plugins/maps/public/actions/map_actions.test.js @@ -5,7 +5,7 @@ */ jest.mock('../selectors/map_selectors', () => ({})); -jest.mock('../../../../../plugins/maps/public/kibana_services', () => ({})); +jest.mock('../kibana_services', () => ({})); import { mapExtentChanged, setMouseCoordinates } from './map_actions'; diff --git a/x-pack/legacy/plugins/maps/public/actions/ui_actions.d.ts b/x-pack/plugins/maps/public/actions/ui_actions.d.ts similarity index 54% rename from x-pack/legacy/plugins/maps/public/actions/ui_actions.d.ts rename to x-pack/plugins/maps/public/actions/ui_actions.d.ts index 233918847de08b..e087dc70256f06 100644 --- a/x-pack/legacy/plugins/maps/public/actions/ui_actions.d.ts +++ b/x-pack/plugins/maps/public/actions/ui_actions.d.ts @@ -6,6 +6,17 @@ import { AnyAction } from 'redux'; +export const UPDATE_FLYOUT: string; +export const CLOSE_SET_VIEW: string; +export const OPEN_SET_VIEW: string; +export const SET_IS_LAYER_TOC_OPEN: string; +export const SET_FULL_SCREEN: string; +export const SET_READ_ONLY: string; +export const SET_OPEN_TOC_DETAILS: string; +export const SHOW_TOC_DETAILS: string; +export const HIDE_TOC_DETAILS: string; +export const UPDATE_INDEXING_STAGE: string; + export function setOpenTOCDetails(layerIds?: string[]): AnyAction; export function setIsLayerTOCOpen(open: boolean): AnyAction; diff --git a/x-pack/plugins/maps/public/actions/ui_actions.js b/x-pack/plugins/maps/public/actions/ui_actions.js index 59ae56c15056a0..77fdf6b0f12d23 100644 --- a/x-pack/plugins/maps/public/actions/ui_actions.js +++ b/x-pack/plugins/maps/public/actions/ui_actions.js @@ -14,3 +14,73 @@ export const SET_OPEN_TOC_DETAILS = 'SET_OPEN_TOC_DETAILS'; export const SHOW_TOC_DETAILS = 'SHOW_TOC_DETAILS'; export const HIDE_TOC_DETAILS = 'HIDE_TOC_DETAILS'; export const UPDATE_INDEXING_STAGE = 'UPDATE_INDEXING_STAGE'; + +export function exitFullScreen() { + return { + type: SET_FULL_SCREEN, + isFullScreen: false, + }; +} + +export function updateFlyout(display) { + return { + type: UPDATE_FLYOUT, + display, + }; +} +export function closeSetView() { + return { + type: CLOSE_SET_VIEW, + }; +} +export function openSetView() { + return { + type: OPEN_SET_VIEW, + }; +} +export function setIsLayerTOCOpen(isLayerTOCOpen) { + return { + type: SET_IS_LAYER_TOC_OPEN, + isLayerTOCOpen, + }; +} +export function enableFullScreen() { + return { + type: SET_FULL_SCREEN, + isFullScreen: true, + }; +} +export function setReadOnly(isReadOnly) { + return { + type: SET_READ_ONLY, + isReadOnly, + }; +} + +export function setOpenTOCDetails(layerIds) { + return { + type: SET_OPEN_TOC_DETAILS, + layerIds, + }; +} + +export function showTOCDetails(layerId) { + return { + type: SHOW_TOC_DETAILS, + layerId, + }; +} + +export function hideTOCDetails(layerId) { + return { + type: HIDE_TOC_DETAILS, + layerId, + }; +} + +export function updateIndexingStage(stage) { + return { + type: UPDATE_INDEXING_STAGE, + stage, + }; +} diff --git a/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.d.ts b/x-pack/plugins/maps/public/angular/get_initial_layers.d.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/angular/get_initial_layers.d.ts rename to x-pack/plugins/maps/public/angular/get_initial_layers.d.ts diff --git a/x-pack/plugins/maps/public/angular/get_initial_layers.js b/x-pack/plugins/maps/public/angular/get_initial_layers.js new file mode 100644 index 00000000000000..1eb5dac309f28c --- /dev/null +++ b/x-pack/plugins/maps/public/angular/get_initial_layers.js @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import _ from 'lodash'; +// Import each layer type, even those not used, to init in registry + +import '../layers/sources/wms_source'; + +import '../layers/sources/ems_file_source'; + +import '../layers/sources/es_search_source'; + +import '../layers/sources/es_pew_pew_source/es_pew_pew_source'; + +import '../layers/sources/kibana_regionmap_source'; + +import '../layers/sources/es_geo_grid_source'; + +import '../layers/sources/xyz_tms_source'; + +import { KibanaTilemapSource } from '../layers/sources/kibana_tilemap_source'; + +import { EMSTMSSource } from '../layers/sources/ems_tms_source'; + +import { getInjectedVarFunc } from '../kibana_services'; + +import { getKibanaTileMap } from '../meta'; + +export function getInitialLayers(layerListJSON, initialLayers = []) { + if (layerListJSON) { + return JSON.parse(layerListJSON); + } + + const tilemapSourceFromKibana = getKibanaTileMap(); + if (_.get(tilemapSourceFromKibana, 'url')) { + const sourceDescriptor = KibanaTilemapSource.createDescriptor(); + const source = new KibanaTilemapSource(sourceDescriptor); + const layer = source.createDefaultLayer(); + return [layer.toLayerDescriptor(), ...initialLayers]; + } + + const isEmsEnabled = getInjectedVarFunc()('isEmsEnabled', true); + if (isEmsEnabled) { + const descriptor = EMSTMSSource.createDescriptor({ isAutoSelect: true }); + const source = new EMSTMSSource(descriptor); + const layer = source.createDefaultLayer(); + return [layer.toLayerDescriptor(), ...initialLayers]; + } + + return initialLayers; +} diff --git a/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.test.js b/x-pack/plugins/maps/public/angular/get_initial_layers.test.js similarity index 80% rename from x-pack/legacy/plugins/maps/public/angular/get_initial_layers.test.js rename to x-pack/plugins/maps/public/angular/get_initial_layers.test.js index 8c9185a16ea0e7..f41ed26b2a05d3 100644 --- a/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.test.js +++ b/x-pack/plugins/maps/public/angular/get_initial_layers.test.js @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -jest.mock('../../../../../plugins/maps/public/meta', () => { +jest.mock('../meta', () => { return {}; }); -jest.mock('../../../../../plugins/maps/public/kibana_services'); +jest.mock('../kibana_services'); import { getInitialLayers } from './get_initial_layers'; @@ -15,8 +15,7 @@ const layerListNotProvided = undefined; describe('Saved object has layer list', () => { beforeEach(() => { - require('../../../../../plugins/maps/public/kibana_services').getInjectedVarFunc = () => - jest.fn(); + require('../kibana_services').getInjectedVarFunc = () => jest.fn(); }); it('Should get initial layers from saved object', () => { @@ -33,7 +32,7 @@ describe('Saved object has layer list', () => { describe('kibana.yml configured with map.tilemap.url', () => { beforeAll(() => { - require('../../../../../plugins/maps/public/meta').getKibanaTileMap = () => { + require('../meta').getKibanaTileMap = () => { return { url: 'myTileUrl', }; @@ -63,10 +62,10 @@ describe('kibana.yml configured with map.tilemap.url', () => { describe('EMS is enabled', () => { beforeAll(() => { - require('../../../../../plugins/maps/public/meta').getKibanaTileMap = () => { + require('../meta').getKibanaTileMap = () => { return null; }; - require('../../../../../plugins/maps/public/kibana_services').getInjectedVarFunc = () => key => { + require('../kibana_services').getInjectedVarFunc = () => key => { switch (key) { case 'emsTileLayerId': return { @@ -107,11 +106,11 @@ describe('EMS is enabled', () => { describe('EMS is not enabled', () => { beforeAll(() => { - require('../../../../../plugins/maps/public/meta').getKibanaTileMap = () => { + require('../meta').getKibanaTileMap = () => { return null; }; - require('../../../../../plugins/maps/public/kibana_services').getInjectedVarFunc = () => key => { + require('../kibana_services').getInjectedVarFunc = () => key => { switch (key) { case 'isEmsEnabled': return false; diff --git a/x-pack/legacy/plugins/maps/public/angular/get_initial_query.js b/x-pack/plugins/maps/public/angular/get_initial_query.js similarity index 82% rename from x-pack/legacy/plugins/maps/public/angular/get_initial_query.js rename to x-pack/plugins/maps/public/angular/get_initial_query.js index c50ecb2b05dc07..4f61142413671d 100644 --- a/x-pack/legacy/plugins/maps/public/angular/get_initial_query.js +++ b/x-pack/plugins/maps/public/angular/get_initial_query.js @@ -4,8 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getUiSettings } from '../../../../../plugins/maps/public/kibana_services'; +import { getUiSettings } from '../kibana_services'; export function getInitialQuery({ mapStateJSON, appState = {}, userQueryLanguage }) { const settings = getUiSettings(); diff --git a/x-pack/legacy/plugins/maps/public/angular/get_initial_refresh_config.js b/x-pack/plugins/maps/public/angular/get_initial_refresh_config.js similarity index 84% rename from x-pack/legacy/plugins/maps/public/angular/get_initial_refresh_config.js rename to x-pack/plugins/maps/public/angular/get_initial_refresh_config.js index 8735d45debfc4c..f13e435cd1d5cf 100644 --- a/x-pack/legacy/plugins/maps/public/angular/get_initial_refresh_config.js +++ b/x-pack/plugins/maps/public/angular/get_initial_refresh_config.js @@ -3,8 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getUiSettings } from '../../../../../plugins/maps/public/kibana_services'; + +import { getUiSettings } from '../kibana_services'; export function getInitialRefreshConfig({ mapStateJSON, globalState = {} }) { const uiSettings = getUiSettings(); diff --git a/x-pack/legacy/plugins/maps/public/angular/get_initial_time_filters.js b/x-pack/plugins/maps/public/angular/get_initial_time_filters.js similarity index 80% rename from x-pack/legacy/plugins/maps/public/angular/get_initial_time_filters.js rename to x-pack/plugins/maps/public/angular/get_initial_time_filters.js index 74fbf603e99f5e..75d9f0e95ccf08 100644 --- a/x-pack/legacy/plugins/maps/public/angular/get_initial_time_filters.js +++ b/x-pack/plugins/maps/public/angular/get_initial_time_filters.js @@ -3,8 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getUiSettings } from '../../../../../plugins/maps/public/kibana_services'; + +import { getUiSettings } from '../kibana_services'; export function getInitialTimeFilters({ mapStateJSON, globalState = {} }) { if (mapStateJSON) { diff --git a/x-pack/legacy/plugins/maps/public/angular/listing_ng_wrapper.html b/x-pack/plugins/maps/public/angular/listing_ng_wrapper.html similarity index 100% rename from x-pack/legacy/plugins/maps/public/angular/listing_ng_wrapper.html rename to x-pack/plugins/maps/public/angular/listing_ng_wrapper.html diff --git a/x-pack/legacy/plugins/maps/public/angular/map.html b/x-pack/plugins/maps/public/angular/map.html similarity index 100% rename from x-pack/legacy/plugins/maps/public/angular/map.html rename to x-pack/plugins/maps/public/angular/map.html diff --git a/x-pack/legacy/plugins/maps/public/angular/services/gis_map_saved_object_loader.js b/x-pack/plugins/maps/public/angular/services/gis_map_saved_object_loader.js similarity index 79% rename from x-pack/legacy/plugins/maps/public/angular/services/gis_map_saved_object_loader.js rename to x-pack/plugins/maps/public/angular/services/gis_map_saved_object_loader.js index 710997a9c0d7f3..2dcec35960b080 100644 --- a/x-pack/legacy/plugins/maps/public/angular/services/gis_map_saved_object_loader.js +++ b/x-pack/plugins/maps/public/angular/services/gis_map_saved_object_loader.js @@ -6,15 +6,14 @@ import _ from 'lodash'; import { createSavedGisMapClass } from './saved_gis_map'; -import { SavedObjectLoader } from '../../../../../../../src/plugins/saved_objects/public'; +import { SavedObjectLoader } from '../../../../../../src/plugins/saved_objects/public'; import { getCoreChrome, getSavedObjectsClient, getIndexPatternService, getCoreOverlays, getData, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../../plugins/maps/public/kibana_services'; +} from '../../kibana_services'; export const getMapsSavedObjectLoader = _.once(function() { const services = { diff --git a/x-pack/legacy/plugins/maps/public/angular/services/saved_gis_map.js b/x-pack/plugins/maps/public/angular/services/saved_gis_map.js similarity index 88% rename from x-pack/legacy/plugins/maps/public/angular/services/saved_gis_map.js rename to x-pack/plugins/maps/public/angular/services/saved_gis_map.js index 990a0613da681c..1c47e0ab7dc2a4 100644 --- a/x-pack/legacy/plugins/maps/public/angular/services/saved_gis_map.js +++ b/x-pack/plugins/maps/public/angular/services/saved_gis_map.js @@ -5,7 +5,7 @@ */ import _ from 'lodash'; -import { createSavedObjectClass } from '../../../../../../../src/plugins/saved_objects/public'; +import { createSavedObjectClass } from '../../../../../../src/plugins/saved_objects/public'; import { getTimeFilters, getMapZoom, @@ -17,10 +17,10 @@ import { getFilters, } from '../../selectors/map_selectors'; import { getIsLayerTOCOpen, getOpenTOCDetails } from '../../selectors/ui_selectors'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { convertMapExtentToPolygon } from '../../../../../../plugins/maps/public/elasticsearch_geo_utils'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { copyPersistentState } from '../../../../../../plugins/maps/public/reducers/util'; + +import { convertMapExtentToPolygon } from '../../elasticsearch_geo_utils'; + +import { copyPersistentState } from '../../reducers/util'; import { extractReferences, injectReferences } from '../../../common/migrations/references'; import { MAP_SAVED_OBJECT_TYPE } from '../../../common/constants'; diff --git a/x-pack/legacy/plugins/maps/public/components/__snapshots__/geometry_filter_form.test.js.snap b/x-pack/plugins/maps/public/components/__snapshots__/geometry_filter_form.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/__snapshots__/geometry_filter_form.test.js.snap rename to x-pack/plugins/maps/public/components/__snapshots__/geometry_filter_form.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/components/__snapshots__/layer_toc_actions.test.js.snap b/x-pack/plugins/maps/public/components/__snapshots__/layer_toc_actions.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/__snapshots__/layer_toc_actions.test.js.snap rename to x-pack/plugins/maps/public/components/__snapshots__/layer_toc_actions.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/components/_geometry_filter.scss b/x-pack/plugins/maps/public/components/_geometry_filter.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/_geometry_filter.scss rename to x-pack/plugins/maps/public/components/_geometry_filter.scss diff --git a/x-pack/plugins/maps/public/components/_index.scss b/x-pack/plugins/maps/public/components/_index.scss new file mode 100644 index 00000000000000..161b3fefdb8f9e --- /dev/null +++ b/x-pack/plugins/maps/public/components/_index.scss @@ -0,0 +1,3 @@ +@import 'metric_editors'; +@import './geometry_filter'; +@import 'tooltip_selector'; diff --git a/x-pack/legacy/plugins/maps/public/components/_metric_editors.scss b/x-pack/plugins/maps/public/components/_metric_editors.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/_metric_editors.scss rename to x-pack/plugins/maps/public/components/_metric_editors.scss diff --git a/x-pack/legacy/plugins/maps/public/components/_tooltip_selector.scss b/x-pack/plugins/maps/public/components/_tooltip_selector.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/_tooltip_selector.scss rename to x-pack/plugins/maps/public/components/_tooltip_selector.scss diff --git a/x-pack/legacy/plugins/maps/public/components/distance_filter_form.tsx b/x-pack/plugins/maps/public/components/distance_filter_form.tsx similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/distance_filter_form.tsx rename to x-pack/plugins/maps/public/components/distance_filter_form.tsx diff --git a/x-pack/legacy/plugins/maps/public/components/geo_field_with_index.ts b/x-pack/plugins/maps/public/components/geo_field_with_index.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/geo_field_with_index.ts rename to x-pack/plugins/maps/public/components/geo_field_with_index.ts diff --git a/x-pack/legacy/plugins/maps/public/components/geometry_filter_form.js b/x-pack/plugins/maps/public/components/geometry_filter_form.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/geometry_filter_form.js rename to x-pack/plugins/maps/public/components/geometry_filter_form.js diff --git a/x-pack/legacy/plugins/maps/public/components/geometry_filter_form.test.js b/x-pack/plugins/maps/public/components/geometry_filter_form.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/geometry_filter_form.test.js rename to x-pack/plugins/maps/public/components/geometry_filter_form.test.js diff --git a/x-pack/legacy/plugins/maps/public/components/global_filter_checkbox.js b/x-pack/plugins/maps/public/components/global_filter_checkbox.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/global_filter_checkbox.js rename to x-pack/plugins/maps/public/components/global_filter_checkbox.js diff --git a/x-pack/legacy/plugins/maps/public/components/layer_toc_actions.js b/x-pack/plugins/maps/public/components/layer_toc_actions.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/layer_toc_actions.js rename to x-pack/plugins/maps/public/components/layer_toc_actions.js diff --git a/x-pack/legacy/plugins/maps/public/components/layer_toc_actions.test.js b/x-pack/plugins/maps/public/components/layer_toc_actions.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/layer_toc_actions.test.js rename to x-pack/plugins/maps/public/components/layer_toc_actions.test.js diff --git a/x-pack/legacy/plugins/maps/public/components/map_listing.js b/x-pack/plugins/maps/public/components/map_listing.js similarity index 98% rename from x-pack/legacy/plugins/maps/public/components/map_listing.js rename to x-pack/plugins/maps/public/components/map_listing.js index ef1d524cb91dd2..ee10fe30130f37 100644 --- a/x-pack/legacy/plugins/maps/public/components/map_listing.js +++ b/x-pack/plugins/maps/public/components/map_listing.js @@ -7,8 +7,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import _ from 'lodash'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getToasts } from '../../../../../plugins/maps/public/kibana_services'; + +import { getToasts } from '../kibana_services'; import { EuiTitle, EuiFieldSearch, diff --git a/x-pack/legacy/plugins/maps/public/components/multi_index_geo_field_select.tsx b/x-pack/plugins/maps/public/components/multi_index_geo_field_select.tsx similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/multi_index_geo_field_select.tsx rename to x-pack/plugins/maps/public/components/multi_index_geo_field_select.tsx diff --git a/x-pack/plugins/maps/public/connected_components/_index.scss b/x-pack/plugins/maps/public/connected_components/_index.scss new file mode 100644 index 00000000000000..83042ae1d586cc --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/_index.scss @@ -0,0 +1,6 @@ +@import 'gis_map/gis_map'; +@import 'layer_addpanel/source_select/index'; +@import 'layer_panel/index'; +@import 'widget_overlay/index'; +@import 'toolbar_overlay/index'; +@import 'map/features_tooltip/index'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/gis_map/_gis_map.scss b/x-pack/plugins/maps/public/connected_components/gis_map/_gis_map.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/gis_map/_gis_map.scss rename to x-pack/plugins/maps/public/connected_components/gis_map/_gis_map.scss diff --git a/x-pack/legacy/plugins/maps/public/connected_components/gis_map/index.d.ts b/x-pack/plugins/maps/public/connected_components/gis_map/index.d.ts similarity index 73% rename from x-pack/legacy/plugins/maps/public/connected_components/gis_map/index.d.ts rename to x-pack/plugins/maps/public/connected_components/gis_map/index.d.ts index 8689d882971719..92d92dfbd142da 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/gis_map/index.d.ts +++ b/x-pack/plugins/maps/public/connected_components/gis_map/index.d.ts @@ -6,8 +6,8 @@ import React from 'react'; import { Filter } from 'src/plugins/data/public'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { RenderToolTipContent } from '../../../../../../plugins/maps/public/layers/tooltips/tooltip_property'; + +import { RenderToolTipContent } from '../../layers/tooltips/tooltip_property'; export const GisMap: React.ComponentType<{ addFilters: ((filters: Filter[]) => void) | null; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/gis_map/index.js b/x-pack/plugins/maps/public/connected_components/gis_map/index.js similarity index 85% rename from x-pack/legacy/plugins/maps/public/connected_components/gis_map/index.js rename to x-pack/plugins/maps/public/connected_components/gis_map/index.js index 2d8265bae93878..c825fdab75ca74 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/gis_map/index.js +++ b/x-pack/plugins/maps/public/connected_components/gis_map/index.js @@ -6,8 +6,8 @@ import { connect } from 'react-redux'; import { GisMap } from './view'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { FLYOUT_STATE } from '../../../../../../plugins/maps/public/reducers/ui'; + +import { FLYOUT_STATE } from '../../reducers/ui'; import { exitFullScreen } from '../../actions/ui_actions'; import { getFlyoutDisplay, getIsFullScreen } from '../../selectors/ui_selectors'; import { triggerRefreshTimer, cancelAllInFlightRequests } from '../../actions/map_actions'; @@ -18,8 +18,8 @@ import { getQueryableUniqueIndexPatternIds, isToolbarOverlayHidden, } from '../../selectors/map_selectors'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getCoreChrome } from '../../../../../../plugins/maps/public/kibana_services'; + +import { getCoreChrome } from '../../kibana_services'; function mapStateToProps(state = {}) { const flyoutDisplay = getFlyoutDisplay(state); diff --git a/x-pack/legacy/plugins/maps/public/connected_components/gis_map/view.js b/x-pack/plugins/maps/public/connected_components/gis_map/view.js similarity index 92% rename from x-pack/legacy/plugins/maps/public/connected_components/gis_map/view.js rename to x-pack/plugins/maps/public/connected_components/gis_map/view.js index 06097ebea1900a..28ad12133d6118 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/gis_map/view.js +++ b/x-pack/plugins/maps/public/connected_components/gis_map/view.js @@ -7,17 +7,16 @@ import _ from 'lodash'; import React, { Component } from 'react'; import { MBMapContainer } from '../map/mb'; -import { WidgetOverlay } from '../widget_overlay/index'; -import { ToolbarOverlay } from '../toolbar_overlay/index'; -import { LayerPanel } from '../layer_panel/index'; -import { AddLayerPanel } from '../layer_addpanel/index'; +import { WidgetOverlay } from '../widget_overlay'; +import { ToolbarOverlay } from '../toolbar_overlay'; +import { LayerPanel } from '../layer_panel'; +import { AddLayerPanel } from '../layer_addpanel'; import { EuiFlexGroup, EuiFlexItem, EuiCallOut } from '@elastic/eui'; -import { ExitFullScreenButton } from '../../../../../../../src/plugins/kibana_react/public'; +import { ExitFullScreenButton } from '../../../../../../src/plugins/kibana_react/public'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getIndexPatternsFromIds } from '../../../../../../plugins/maps/public/index_pattern_util'; +import { getIndexPatternsFromIds } from '../../index_pattern_util'; import { ES_GEO_FIELD_TYPE } from '../../../common/constants'; -import { indexPatterns as indexPatternsUtils } from '../../../../../../../src/plugins/data/public'; +import { indexPatterns as indexPatternsUtils } from '../../../../../../src/plugins/data/public'; import { i18n } from '@kbn/i18n'; import uuid from 'uuid/v4'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/flyout_footer/index.js b/x-pack/plugins/maps/public/connected_components/layer_addpanel/flyout_footer/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/flyout_footer/index.js rename to x-pack/plugins/maps/public/connected_components/layer_addpanel/flyout_footer/index.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/flyout_footer/view.js b/x-pack/plugins/maps/public/connected_components/layer_addpanel/flyout_footer/view.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/flyout_footer/view.js rename to x-pack/plugins/maps/public/connected_components/layer_addpanel/flyout_footer/view.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/import_editor/index.js b/x-pack/plugins/maps/public/connected_components/layer_addpanel/import_editor/index.js similarity index 76% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/import_editor/index.js rename to x-pack/plugins/maps/public/connected_components/layer_addpanel/import_editor/index.js index e8192795f98aef..bff235a7d27fcd 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/import_editor/index.js +++ b/x-pack/plugins/maps/public/connected_components/layer_addpanel/import_editor/index.js @@ -6,10 +6,10 @@ import { connect } from 'react-redux'; import { ImportEditor } from './view'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getInspectorAdapters } from '../../../../../../../plugins/maps/public/reducers/non_serializable_instances'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { INDEXING_STAGE } from '../../../../../../../plugins/maps/public/reducers/ui'; + +import { getInspectorAdapters } from '../../../reducers/non_serializable_instances'; + +import { INDEXING_STAGE } from '../../../reducers/ui'; import { updateIndexingStage } from '../../../actions/ui_actions'; import { getIndexingStage } from '../../../selectors/ui_selectors'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/import_editor/view.js b/x-pack/plugins/maps/public/connected_components/layer_addpanel/import_editor/view.js similarity index 89% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/import_editor/view.js rename to x-pack/plugins/maps/public/connected_components/layer_addpanel/import_editor/view.js index cb20d80733c33b..a4fa0d492bf3f5 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/import_editor/view.js +++ b/x-pack/plugins/maps/public/connected_components/layer_addpanel/import_editor/view.js @@ -7,8 +7,8 @@ import React, { Fragment } from 'react'; import { EuiSpacer, EuiPanel, EuiButtonEmpty } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { uploadLayerWizardConfig } from '../../../../../../../plugins/maps/public/layers/sources/client_file_source'; + +import { uploadLayerWizardConfig } from '../../../layers/sources/client_file_source'; export const ImportEditor = ({ clearSource, isIndexingTriggered, ...props }) => { const editorProperties = getEditorProperties({ isIndexingTriggered, ...props }); diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/index.js b/x-pack/plugins/maps/public/connected_components/layer_addpanel/index.js similarity index 85% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/index.js rename to x-pack/plugins/maps/public/connected_components/layer_addpanel/index.js index c4e2fa5169b0fa..24c1f5ced4fe65 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/index.js +++ b/x-pack/plugins/maps/public/connected_components/layer_addpanel/index.js @@ -6,13 +6,13 @@ import { connect } from 'react-redux'; import { AddLayerPanel } from './view'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { FLYOUT_STATE, INDEXING_STAGE } from '../../../../../../plugins/maps/public/reducers/ui'; + +import { FLYOUT_STATE, INDEXING_STAGE } from '../../reducers/ui'; import { updateFlyout, updateIndexingStage } from '../../actions/ui_actions'; import { getFlyoutDisplay, getIndexingStage } from '../../selectors/ui_selectors'; import { getMapColors } from '../../selectors/map_selectors'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getInspectorAdapters } from '../../../../../../plugins/maps/public/reducers/non_serializable_instances'; + +import { getInspectorAdapters } from '../../reducers/non_serializable_instances'; import { setTransientLayer, addLayer, diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/source_editor/index.js b/x-pack/plugins/maps/public/connected_components/layer_addpanel/source_editor/index.js similarity index 75% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/source_editor/index.js rename to x-pack/plugins/maps/public/connected_components/layer_addpanel/source_editor/index.js index 553e54ee897665..8937f32d3bf05d 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/source_editor/index.js +++ b/x-pack/plugins/maps/public/connected_components/layer_addpanel/source_editor/index.js @@ -6,8 +6,8 @@ import { connect } from 'react-redux'; import { SourceEditor } from './view'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getInspectorAdapters } from '../../../../../../../plugins/maps/public/reducers/non_serializable_instances'; + +import { getInspectorAdapters } from '../../../reducers/non_serializable_instances'; function mapStateToProps(state = {}) { return { diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/source_editor/view.js b/x-pack/plugins/maps/public/connected_components/layer_addpanel/source_editor/view.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/source_editor/view.js rename to x-pack/plugins/maps/public/connected_components/layer_addpanel/source_editor/view.js diff --git a/x-pack/plugins/maps/public/connected_components/layer_addpanel/source_select/_index.scss b/x-pack/plugins/maps/public/connected_components/layer_addpanel/source_select/_index.scss new file mode 100644 index 00000000000000..8ae6970315e132 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/layer_addpanel/source_select/_index.scss @@ -0,0 +1 @@ +@import 'source_select'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/source_select/_source_select.scss b/x-pack/plugins/maps/public/connected_components/layer_addpanel/source_select/_source_select.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/source_select/_source_select.scss rename to x-pack/plugins/maps/public/connected_components/layer_addpanel/source_select/_source_select.scss diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/source_select/source_select.js b/x-pack/plugins/maps/public/connected_components/layer_addpanel/source_select/source_select.js similarity index 90% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/source_select/source_select.js rename to x-pack/plugins/maps/public/connected_components/layer_addpanel/source_select/source_select.js index 67cc17ebaa2241..80b05a0fd015b7 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/source_select/source_select.js +++ b/x-pack/plugins/maps/public/connected_components/layer_addpanel/source_select/source_select.js @@ -5,8 +5,8 @@ */ import React, { Fragment } from 'react'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getLayerWizards } from '../../../../../../../plugins/maps/public/layers/layer_wizard_registry'; + +import { getLayerWizards } from '../../../layers/layer_wizard_registry'; import { EuiTitle, EuiSpacer, EuiCard, EuiIcon } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import _ from 'lodash'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/view.js b/x-pack/plugins/maps/public/connected_components/layer_addpanel/view.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/view.js rename to x-pack/plugins/maps/public/connected_components/layer_addpanel/view.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/__snapshots__/view.test.js.snap b/x-pack/plugins/maps/public/connected_components/layer_panel/__snapshots__/view.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/__snapshots__/view.test.js.snap rename to x-pack/plugins/maps/public/connected_components/layer_panel/__snapshots__/view.test.js.snap diff --git a/x-pack/plugins/maps/public/connected_components/layer_panel/_index.scss b/x-pack/plugins/maps/public/connected_components/layer_panel/_index.scss new file mode 100644 index 00000000000000..41b4826a02c675 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/layer_panel/_index.scss @@ -0,0 +1,4 @@ +@import 'layer_panel'; +@import 'filter_editor/filter_editor'; +@import 'join_editor/resources/join'; +@import 'style_settings/style_settings'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/_layer_panel.scss b/x-pack/plugins/maps/public/connected_components/layer_panel/_layer_panel.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/_layer_panel.scss rename to x-pack/plugins/maps/public/connected_components/layer_panel/_layer_panel.scss diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/filter_editor/_filter_editor.scss b/x-pack/plugins/maps/public/connected_components/layer_panel/filter_editor/_filter_editor.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/filter_editor/_filter_editor.scss rename to x-pack/plugins/maps/public/connected_components/layer_panel/filter_editor/_filter_editor.scss diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/filter_editor/filter_editor.js b/x-pack/plugins/maps/public/connected_components/layer_panel/filter_editor/filter_editor.js similarity index 96% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/filter_editor/filter_editor.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/filter_editor/filter_editor.js index 40fdac38493d4b..fba2ec05d0b1d6 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/filter_editor/filter_editor.js +++ b/x-pack/plugins/maps/public/connected_components/layer_panel/filter_editor/filter_editor.js @@ -20,12 +20,7 @@ import { import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { - getIndexPatternService, - getUiSettings, - getData, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../../../plugins/maps/public/kibana_services'; +import { getIndexPatternService, getUiSettings, getData } from '../../../kibana_services'; import { GlobalFilterCheckbox } from '../../../components/global_filter_checkbox'; export class FilterEditor extends Component { diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/filter_editor/index.js b/x-pack/plugins/maps/public/connected_components/layer_panel/filter_editor/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/filter_editor/index.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/filter_editor/index.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/flyout_footer/index.js b/x-pack/plugins/maps/public/connected_components/layer_panel/flyout_footer/index.js similarity index 89% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/flyout_footer/index.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/flyout_footer/index.js index 287f0019f18ecd..621ce209eb982f 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/flyout_footer/index.js +++ b/x-pack/plugins/maps/public/connected_components/layer_panel/flyout_footer/index.js @@ -6,8 +6,8 @@ import { connect } from 'react-redux'; import { FlyoutFooter } from './view'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { FLYOUT_STATE } from '../../../../../../../plugins/maps/public/reducers/ui'; + +import { FLYOUT_STATE } from '../../../reducers/ui'; import { updateFlyout } from '../../../actions/ui_actions'; import { hasDirtyState } from '../../../selectors/map_selectors'; import { diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/flyout_footer/view.js b/x-pack/plugins/maps/public/connected_components/layer_panel/flyout_footer/view.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/flyout_footer/view.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/flyout_footer/view.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/index.js b/x-pack/plugins/maps/public/connected_components/layer_panel/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/index.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/index.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/index.js b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/index.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/index.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/__snapshots__/metrics_expression.test.js.snap b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/__snapshots__/metrics_expression.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/__snapshots__/metrics_expression.test.js.snap rename to x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/__snapshots__/metrics_expression.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/_join.scss b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/_join.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/_join.scss rename to x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/_join.scss diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join.js b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join.js similarity index 95% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join.js index 9c4e1cfdb5467c..0d26354e2449b2 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join.js +++ b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join.js @@ -13,9 +13,9 @@ import { MetricsExpression } from './metrics_expression'; import { WhereExpression } from './where_expression'; import { GlobalFilterCheckbox } from '../../../../components/global_filter_checkbox'; -import { indexPatterns } from '../../../../../../../../../src/plugins/data/public'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getIndexPatternService } from '../../../../../../../../plugins/maps/public/kibana_services'; +import { indexPatterns } from '../../../../../../../../src/plugins/data/public'; + +import { getIndexPatternService } from '../../../../kibana_services'; export class Join extends Component { state = { diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join_expression.js b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join_expression.js similarity index 93% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join_expression.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join_expression.js index 73600c81d221e2..12ca2f3c514a06 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join_expression.js +++ b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join_expression.js @@ -16,16 +16,15 @@ import { EuiFormHelpText, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { SingleFieldSelect } from '../../../../../../../../plugins/maps/public/components/single_field_select'; + +import { SingleFieldSelect } from '../../../../components/single_field_select'; import { FormattedMessage } from '@kbn/i18n/react'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getTermsFields } from '../../../../../../../../plugins/maps/public/index_pattern_util'; + +import { getTermsFields } from '../../../../index_pattern_util'; import { getIndexPatternService, getIndexPatternSelectComponent, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../../../../plugins/maps/public/kibana_services'; +} from '../../../../kibana_services'; export class JoinExpression extends Component { state = { diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.js b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.js similarity index 95% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.js index c6a79a398f9af2..8c83743ac4c962 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.js +++ b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.js @@ -14,8 +14,8 @@ import { EuiFormErrorText, EuiFormHelpText, } from '@elastic/eui'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { MetricsEditor } from '../../../../../../../../plugins/maps/public/components/metrics_editor'; + +import { MetricsEditor } from '../../../../components/metrics_editor'; import { FormattedMessage } from '@kbn/i18n/react'; import { AGG_TYPE } from '../../../../../common/constants'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js similarity index 92% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js index d8bf8622494484..3cd8a3c42879a3 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js +++ b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -jest.mock('../../../../../../../../plugins/maps/public/components/metric_editor', () => ({ +jest.mock('../../../../components/metric_editor', () => ({ MetricsEditor: () => { return
mockMetricsEditor
; }, diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/where_expression.js b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/where_expression.js similarity index 94% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/where_expression.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/where_expression.js index 54ec0ac46fa3d9..7c9b4f7b7b9a4d 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/where_expression.js +++ b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/where_expression.js @@ -8,11 +8,7 @@ import React, { Component } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButton, EuiPopover, EuiExpression, EuiFormHelpText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { - getUiSettings, - getData, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../../../../plugins/maps/public/kibana_services'; +import { getUiSettings, getData } from '../../../../kibana_services'; export class WhereExpression extends Component { state = { diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/view.js b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/view.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/view.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/view.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_errors/__snapshots__/layer_errors.test.js.snap b/x-pack/plugins/maps/public/connected_components/layer_panel/layer_errors/__snapshots__/layer_errors.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_errors/__snapshots__/layer_errors.test.js.snap rename to x-pack/plugins/maps/public/connected_components/layer_panel/layer_errors/__snapshots__/layer_errors.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_errors/index.js b/x-pack/plugins/maps/public/connected_components/layer_panel/layer_errors/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_errors/index.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/layer_errors/index.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_errors/layer_errors.js b/x-pack/plugins/maps/public/connected_components/layer_panel/layer_errors/layer_errors.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_errors/layer_errors.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/layer_errors/layer_errors.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_errors/layer_errors.test.js b/x-pack/plugins/maps/public/connected_components/layer_panel/layer_errors/layer_errors.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_errors/layer_errors.test.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/layer_errors/layer_errors.test.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/index.js b/x-pack/plugins/maps/public/connected_components/layer_panel/layer_settings/index.js similarity index 94% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/index.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/layer_settings/index.js index e8f980bbbf2b40..e2f22c584d3b31 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/index.js +++ b/x-pack/plugins/maps/public/connected_components/layer_panel/layer_settings/index.js @@ -13,7 +13,7 @@ import { updateLayerMinZoom, updateLayerAlpha, } from '../../../actions/map_actions'; -import { MAX_ZOOM } from '../../../../../../../plugins/maps/common/constants'; +import { MAX_ZOOM } from '../../../../common/constants'; function mapStateToProps(state = {}) { const selectedLayer = getSelectedLayer(state); diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js b/x-pack/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js similarity index 92% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js index 1d352913e54a36..168c735ab7a6c1 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js +++ b/x-pack/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js @@ -8,11 +8,10 @@ import React, { Fragment } from 'react'; import { EuiTitle, EuiPanel, EuiFormRow, EuiFieldText, EuiSpacer } from '@elastic/eui'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ValidatedRange } from '../../../../../../../plugins/maps/public/components/validated_range'; +import { ValidatedRange } from '../../../components/validated_range'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { ValidatedDualRange } from '../../../../../../../../src/plugins/kibana_react/public'; +import { ValidatedDualRange } from '../../../../../../../src/plugins/kibana_react/public'; export function LayerSettings(props) { const onLabelChange = event => { const label = event.target.value; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/style_settings/_style_settings.scss b/x-pack/plugins/maps/public/connected_components/layer_panel/style_settings/_style_settings.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/style_settings/_style_settings.scss rename to x-pack/plugins/maps/public/connected_components/layer_panel/style_settings/_style_settings.scss diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/style_settings/index.js b/x-pack/plugins/maps/public/connected_components/layer_panel/style_settings/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/style_settings/index.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/style_settings/index.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/style_settings/style_settings.js b/x-pack/plugins/maps/public/connected_components/layer_panel/style_settings/style_settings.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/style_settings/style_settings.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/style_settings/style_settings.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/view.js b/x-pack/plugins/maps/public/connected_components/layer_panel/view.js similarity index 95% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/view.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/view.js index 2521318f0b3c9c..f8b7c417e67fd2 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/view.js +++ b/x-pack/plugins/maps/public/connected_components/layer_panel/view.js @@ -28,10 +28,10 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public'; -import { Storage } from '../../../../../../../src/plugins/kibana_utils/public'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getData, getCore } from '../../../../../../plugins/maps/public/kibana_services'; +import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public'; +import { Storage } from '../../../../../../src/plugins/kibana_utils/public'; + +import { getData, getCore } from '../../kibana_services'; const localStorage = new Storage(window.localStorage); diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/view.test.js b/x-pack/plugins/maps/public/connected_components/layer_panel/view.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/layer_panel/view.test.js rename to x-pack/plugins/maps/public/connected_components/layer_panel/view.test.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/__snapshots__/feature_properties.test.js.snap b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/__snapshots__/feature_properties.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/__snapshots__/feature_properties.test.js.snap rename to x-pack/plugins/maps/public/connected_components/map/features_tooltip/__snapshots__/feature_properties.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/__snapshots__/tooltip_header.test.js.snap b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/__snapshots__/tooltip_header.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/__snapshots__/tooltip_header.test.js.snap rename to x-pack/plugins/maps/public/connected_components/map/features_tooltip/__snapshots__/tooltip_header.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/_index.scss b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/_index.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/_index.scss rename to x-pack/plugins/maps/public/connected_components/map/features_tooltip/_index.scss diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/feature_geometry_filter_form.js b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_geometry_filter_form.js similarity index 92% rename from x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/feature_geometry_filter_form.js rename to x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_geometry_filter_form.js index 15824b82965e83..b103fb43af97c7 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/feature_geometry_filter_form.js +++ b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_geometry_filter_form.js @@ -8,12 +8,12 @@ import React, { Component, Fragment } from 'react'; import { EuiIcon } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { createSpatialFilterWithGeometry } from '../../../../../../../plugins/maps/public/elasticsearch_geo_utils'; + +import { createSpatialFilterWithGeometry } from '../../../elasticsearch_geo_utils'; import { GEO_JSON_TYPE } from '../../../../common/constants'; import { GeometryFilterForm } from '../../../components/geometry_filter_form'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { UrlOverflowService } from '../../../../../../../../src/plugins/kibana_legacy/public'; + +import { UrlOverflowService } from '../../../../../../../src/plugins/kibana_legacy/public'; import rison from 'rison-node'; // over estimated and imprecise value to ensure filter has additional room for any meta keys added when filter is mapped. diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.js b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.js rename to x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.test.js b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.test.js rename to x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.test.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/features_tooltip.js b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/features_tooltip.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/features_tooltip.js rename to x-pack/plugins/maps/public/connected_components/map/features_tooltip/features_tooltip.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/tooltip_header.js b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/tooltip_header.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/tooltip_header.js rename to x-pack/plugins/maps/public/connected_components/map/features_tooltip/tooltip_header.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/tooltip_header.test.js b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/tooltip_header.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/tooltip_header.test.js rename to x-pack/plugins/maps/public/connected_components/map/features_tooltip/tooltip_header.test.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/draw_control/draw_circle.ts b/x-pack/plugins/maps/public/connected_components/map/mb/draw_control/draw_circle.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/mb/draw_control/draw_circle.ts rename to x-pack/plugins/maps/public/connected_components/map/mb/draw_control/draw_circle.ts diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/draw_control/draw_control.js b/x-pack/plugins/maps/public/connected_components/map/mb/draw_control/draw_control.js similarity index 96% rename from x-pack/legacy/plugins/maps/public/connected_components/map/mb/draw_control/draw_control.js rename to x-pack/plugins/maps/public/connected_components/map/mb/draw_control/draw_control.js index cc0e665525036f..d20faa39d6492a 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/draw_control/draw_control.js +++ b/x-pack/plugins/maps/public/connected_components/map/mb/draw_control/draw_control.js @@ -15,8 +15,7 @@ import { createSpatialFilterWithGeometry, getBoundingBoxGeometry, roundCoordinates, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../../../../plugins/maps/public/elasticsearch_geo_utils'; +} from '../../../../elasticsearch_geo_utils'; import { DrawTooltip } from './draw_tooltip'; const mbDrawModes = MapboxDraw.modes; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/draw_control/draw_tooltip.js b/x-pack/plugins/maps/public/connected_components/map/mb/draw_control/draw_tooltip.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/mb/draw_control/draw_tooltip.js rename to x-pack/plugins/maps/public/connected_components/map/mb/draw_control/draw_tooltip.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/draw_control/index.js b/x-pack/plugins/maps/public/connected_components/map/mb/draw_control/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/mb/draw_control/index.js rename to x-pack/plugins/maps/public/connected_components/map/mb/draw_control/index.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/index.js b/x-pack/plugins/maps/public/connected_components/map/mb/index.js similarity index 91% rename from x-pack/legacy/plugins/maps/public/connected_components/map/mb/index.js rename to x-pack/plugins/maps/public/connected_components/map/mb/index.js index 350cb7028abee2..d864b60eb433bf 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/index.js +++ b/x-pack/plugins/maps/public/connected_components/map/mb/index.js @@ -24,8 +24,8 @@ import { isTooltipControlDisabled, isViewControlHidden, } from '../../../selectors/map_selectors'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getInspectorAdapters } from '../../../../../../../plugins/maps/public/reducers/non_serializable_instances'; + +import { getInspectorAdapters } from '../../../reducers/non_serializable_instances'; function mapStateToProps(state = {}) { return { diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/mb.utils.test.js b/x-pack/plugins/maps/public/connected_components/map/mb/mb.utils.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/mb/mb.utils.test.js rename to x-pack/plugins/maps/public/connected_components/map/mb/mb.utils.test.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/__snapshots__/tooltip_control.test.js.snap b/x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/__snapshots__/tooltip_control.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/__snapshots__/tooltip_control.test.js.snap rename to x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/__snapshots__/tooltip_control.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/__snapshots__/tooltip_popover.test.js.snap b/x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/__snapshots__/tooltip_popover.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/__snapshots__/tooltip_popover.test.js.snap rename to x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/__snapshots__/tooltip_popover.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/index.js b/x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/index.js rename to x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/index.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.js b/x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.js rename to x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.test.js b/x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.test.js rename to x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.test.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_popover.js b/x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_popover.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_popover.js rename to x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_popover.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_popover.test.js b/x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_popover.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_popover.test.js rename to x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_popover.test.js diff --git a/x-pack/plugins/maps/public/connected_components/map/mb/utils.js b/x-pack/plugins/maps/public/connected_components/map/mb/utils.js index 15aacfbf1f38db..7be2cd9e670843 100644 --- a/x-pack/plugins/maps/public/connected_components/map/mb/utils.js +++ b/x-pack/plugins/maps/public/connected_components/map/mb/utils.js @@ -4,8 +4,102 @@ * you may not use this file except in compliance with the Elastic License. */ +import _ from 'lodash'; import { RGBAImage } from './image_utils'; +export function removeOrphanedSourcesAndLayers(mbMap, layerList) { + const mbStyle = mbMap.getStyle(); + + const mbLayerIdsToRemove = []; + mbStyle.layers.forEach(mbLayer => { + const layer = layerList.find(layer => { + return layer.ownsMbLayerId(mbLayer.id); + }); + if (!layer) { + mbLayerIdsToRemove.push(mbLayer.id); + } + }); + mbLayerIdsToRemove.forEach(mbLayerId => mbMap.removeLayer(mbLayerId)); + + const mbSourcesToRemove = []; + for (const mbSourceId in mbStyle.sources) { + if (mbStyle.sources.hasOwnProperty(mbSourceId)) { + const layer = layerList.find(layer => { + return layer.ownsMbSourceId(mbSourceId); + }); + if (!layer) { + mbSourcesToRemove.push(mbSourceId); + } + } + } + mbSourcesToRemove.forEach(mbSourceId => mbMap.removeSource(mbSourceId)); +} + +/** + * This is function assumes only a single layer moved in the layerList, compared to mbMap + * It is optimized to minimize the amount of mbMap.moveLayer calls. + * @param mbMap + * @param layerList + */ +export function syncLayerOrderForSingleLayer(mbMap, layerList) { + if (!layerList || layerList.length === 0) { + return; + } + + const mbLayers = mbMap.getStyle().layers.slice(); + const layerIds = mbLayers.map(mbLayer => { + const layer = layerList.find(layer => layer.ownsMbLayerId(mbLayer.id)); + return layer.getId(); + }); + + const currentLayerOrderLayerIds = _.uniq(layerIds); + + const newLayerOrderLayerIdsUnfiltered = layerList.map(l => l.getId()); + const newLayerOrderLayerIds = newLayerOrderLayerIdsUnfiltered.filter(layerId => + currentLayerOrderLayerIds.includes(layerId) + ); + + let netPos = 0; + let netNeg = 0; + const movementArr = currentLayerOrderLayerIds.reduce((accu, id, idx) => { + const movement = newLayerOrderLayerIds.findIndex(newOId => newOId === id) - idx; + movement > 0 ? netPos++ : movement < 0 && netNeg++; + accu.push({ id, movement }); + return accu; + }, []); + if (netPos === 0 && netNeg === 0) { + return; + } + const movedLayerId = + (netPos >= netNeg && movementArr.find(l => l.movement < 0).id) || + (netPos < netNeg && movementArr.find(l => l.movement > 0).id); + const nextLayerIdx = newLayerOrderLayerIds.findIndex(layerId => layerId === movedLayerId) + 1; + + let nextMbLayerId; + if (nextLayerIdx === newLayerOrderLayerIds.length) { + nextMbLayerId = null; + } else { + const foundLayer = mbLayers.find(({ id: mbLayerId }) => { + const layerId = newLayerOrderLayerIds[nextLayerIdx]; + const layer = layerList.find(layer => layer.getId() === layerId); + return layer.ownsMbLayerId(mbLayerId); + }); + nextMbLayerId = foundLayer.id; + } + + const movedLayer = layerList.find(layer => layer.getId() === movedLayerId); + mbLayers.forEach(({ id: mbLayerId }) => { + if (movedLayer.ownsMbLayerId(mbLayerId)) { + mbMap.moveLayer(mbLayerId, nextMbLayerId); + } + }); +} + +export async function addSpritesheetToMap(json, imgUrl, mbMap) { + const imgData = await loadSpriteSheetImageData(imgUrl); + addSpriteSheetToMapFromImageData(json, imgData, mbMap); +} + function getImageData(img) { const canvas = window.document.createElement('canvas'); const context = canvas.getContext('2d'); diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js b/x-pack/plugins/maps/public/connected_components/map/mb/view.js similarity index 94% rename from x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js rename to x-pack/plugins/maps/public/connected_components/map/mb/view.js index a36e1d7048e92f..2d95de184f0f4e 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js +++ b/x-pack/plugins/maps/public/connected_components/map/mb/view.js @@ -6,14 +6,14 @@ import _ from 'lodash'; import React from 'react'; -import { ResizeChecker } from '../../../../../../../../src/plugins/kibana_utils/public'; +import { ResizeChecker } from '../../../../../../../src/plugins/kibana_utils/public'; import { syncLayerOrderForSingleLayer, removeOrphanedSourcesAndLayers, addSpritesheetToMap, } from './utils'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getGlyphUrl, isRetina } from '../../../../../../../plugins/maps/public/meta'; + +import { getGlyphUrl, isRetina } from '../../../meta'; import { DECIMAL_DEGREES_PRECISION, MAX_ZOOM, @@ -28,13 +28,9 @@ import sprites1 from '@elastic/maki/dist/sprite@1.png'; import sprites2 from '@elastic/maki/dist/sprite@2.png'; import { DrawControl } from './draw_control'; import { TooltipControl } from './tooltip_control'; -import { - clampToLatBounds, - clampToLonBounds, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../../../plugins/maps/public/elasticsearch_geo_utils'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getInjectedVarFunc } from '../../../../../../../plugins/maps/public/kibana_services'; +import { clampToLatBounds, clampToLonBounds } from '../../../elasticsearch_geo_utils'; + +import { getInjectedVarFunc } from '../../../kibana_services'; mapboxgl.workerUrl = mbWorkerUrl; mapboxgl.setRTLTextPlugin(mbRtlPlugin); diff --git a/x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/_index.scss b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_index.scss similarity index 93% rename from x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/_index.scss rename to x-pack/plugins/maps/public/connected_components/toolbar_overlay/_index.scss index 01aea403b27f09..2754a3e204263f 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/_index.scss +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_index.scss @@ -1,4 +1,4 @@ -@import './tools_control/index'; +@import 'tools_control/index'; .mapToolbarOverlay { position: absolute; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/index.js b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/index.js rename to x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/index.js b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/index.js rename to x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/index.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/set_view_control.js b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/set_view_control.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/set_view_control.js rename to x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/set_view_control.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.js b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.js rename to x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.js.snap b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.js.snap rename to x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/tools_control/_index.scss b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/_index.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/tools_control/_index.scss rename to x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/_index.scss diff --git a/x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.js b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.js rename to x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.js b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.js rename to x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.js b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.js rename to x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.js diff --git a/x-pack/plugins/maps/public/connected_components/widget_overlay/_index.scss b/x-pack/plugins/maps/public/connected_components/widget_overlay/_index.scss new file mode 100644 index 00000000000000..5e5086bed2763f --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/widget_overlay/_index.scss @@ -0,0 +1,6 @@ +@import 'mixins'; + +@import 'widget_overlay'; +@import 'attribution_control/attribution_control'; +@import 'layer_control/index'; +@import 'view_control/view_control'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/_mixins.scss b/x-pack/plugins/maps/public/connected_components/widget_overlay/_mixins.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/_mixins.scss rename to x-pack/plugins/maps/public/connected_components/widget_overlay/_mixins.scss diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/_widget_overlay.scss b/x-pack/plugins/maps/public/connected_components/widget_overlay/_widget_overlay.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/_widget_overlay.scss rename to x-pack/plugins/maps/public/connected_components/widget_overlay/_widget_overlay.scss diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/__snapshots__/view.test.js.snap b/x-pack/plugins/maps/public/connected_components/widget_overlay/attribution_control/__snapshots__/view.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/__snapshots__/view.test.js.snap rename to x-pack/plugins/maps/public/connected_components/widget_overlay/attribution_control/__snapshots__/view.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/_attribution_control.scss b/x-pack/plugins/maps/public/connected_components/widget_overlay/attribution_control/_attribution_control.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/_attribution_control.scss rename to x-pack/plugins/maps/public/connected_components/widget_overlay/attribution_control/_attribution_control.scss diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/index.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/attribution_control/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/index.js rename to x-pack/plugins/maps/public/connected_components/widget_overlay/attribution_control/index.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/view.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/attribution_control/view.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/view.js rename to x-pack/plugins/maps/public/connected_components/widget_overlay/attribution_control/view.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/view.test.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/attribution_control/view.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/view.test.js rename to x-pack/plugins/maps/public/connected_components/widget_overlay/attribution_control/view.test.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/index.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/index.js rename to x-pack/plugins/maps/public/connected_components/widget_overlay/index.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/__snapshots__/view.test.js.snap b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/__snapshots__/view.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/__snapshots__/view.test.js.snap rename to x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/__snapshots__/view.test.js.snap diff --git a/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/_index.scss b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/_index.scss new file mode 100644 index 00000000000000..9a3e3a45d6c4e5 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/_index.scss @@ -0,0 +1,2 @@ +@import 'layer_control'; +@import 'layer_toc/toc_entry/toc_entry'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/_layer_control.scss b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/_layer_control.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/_layer_control.scss rename to x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/_layer_control.scss diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/index.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/index.js similarity index 90% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/index.js rename to x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/index.js index 04de5f71f5bfc4..8780bac59e4b72 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/index.js +++ b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/index.js @@ -6,8 +6,8 @@ import { connect } from 'react-redux'; import { LayerControl } from './view'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { FLYOUT_STATE } from '../../../../../../../plugins/maps/public/reducers/ui'; + +import { FLYOUT_STATE } from '../../../reducers/ui'; import { updateFlyout, setIsLayerTOCOpen } from '../../../actions/ui_actions'; import { setSelectedLayer } from '../../../actions/map_actions'; import { diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/__snapshots__/view.test.js.snap b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/__snapshots__/view.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/__snapshots__/view.test.js.snap rename to x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/__snapshots__/view.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/index.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/index.js rename to x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/index.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/__snapshots__/view.test.js.snap b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/__snapshots__/view.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/__snapshots__/view.test.js.snap rename to x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/__snapshots__/view.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/_toc_entry.scss b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/_toc_entry.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/_toc_entry.scss rename to x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/_toc_entry.scss diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/index.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/index.js similarity index 93% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/index.js rename to x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/index.js index 588445d0b49928..ca3c6d325687dd 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/index.js +++ b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/index.js @@ -7,8 +7,8 @@ import _ from 'lodash'; import { connect } from 'react-redux'; import { TOCEntry } from './view'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { FLYOUT_STATE } from '../../../../../../../../../plugins/maps/public/reducers/ui'; + +import { FLYOUT_STATE } from '../../../../../reducers/ui'; import { updateFlyout, hideTOCDetails, showTOCDetails } from '../../../../../actions/ui_actions'; import { getIsReadOnly, getOpenTOCDetails } from '../../../../../selectors/ui_selectors'; import { diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/view.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/view.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/view.js rename to x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/view.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/view.test.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/view.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/view.test.js rename to x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/view.test.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/view.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/view.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/view.js rename to x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/view.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/view.test.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/view.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/view.test.js rename to x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/view.test.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/view.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/view.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/view.js rename to x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/view.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/view.test.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/view.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/layer_control/view.test.js rename to x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/view.test.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/view_control/_view_control.scss b/x-pack/plugins/maps/public/connected_components/widget_overlay/view_control/_view_control.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/view_control/_view_control.scss rename to x-pack/plugins/maps/public/connected_components/widget_overlay/view_control/_view_control.scss diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/view_control/index.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/view_control/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/view_control/index.js rename to x-pack/plugins/maps/public/connected_components/widget_overlay/view_control/index.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/view_control/view_control.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/view_control/view_control.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/view_control/view_control.js rename to x-pack/plugins/maps/public/connected_components/widget_overlay/view_control/view_control.js diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/widget_overlay.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/widget_overlay.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/widget_overlay.js rename to x-pack/plugins/maps/public/connected_components/widget_overlay/widget_overlay.js diff --git a/x-pack/plugins/maps/public/elasticsearch_geo_utils.js b/x-pack/plugins/maps/public/elasticsearch_geo_utils.js index 617cf537fd5c31..417c5d84f8916e 100644 --- a/x-pack/plugins/maps/public/elasticsearch_geo_utils.js +++ b/x-pack/plugins/maps/public/elasticsearch_geo_utils.js @@ -64,7 +64,7 @@ function ensureGeometryType(type, expectedTypes) { * @param {string} geoFieldType Geometry field type ["geo_point", "geo_shape"] * @returns {number} */ -export function hitsToGeoJson(hits, flattenHit, geoFieldName, geoFieldType) { +export function hitsToGeoJson(hits, flattenHit, geoFieldName, geoFieldType, epochMillisFields) { const features = []; const tmpGeometriesAccumulator = []; @@ -80,6 +80,16 @@ export function hitsToGeoJson(hits, flattenHit, geoFieldName, geoFieldType) { geoShapeToGeometry(properties[geoFieldName], tmpGeometriesAccumulator); } + // There is a bug in Elasticsearch API where epoch_millis are returned as a string instead of a number + // https://github.com/elastic/elasticsearch/issues/50622 + // Convert these field values to integers. + for (let i = 0; i < epochMillisFields.length; i++) { + const fieldName = epochMillisFields[i]; + if (typeof properties[fieldName] === 'string') { + properties[fieldName] = parseInt(properties[fieldName]); + } + } + // don't include geometry field value in properties delete properties[geoFieldName]; diff --git a/x-pack/plugins/maps/public/elasticsearch_geo_utils.test.js b/x-pack/plugins/maps/public/elasticsearch_geo_utils.test.js index 5db7556be4639d..fc02e191738432 100644 --- a/x-pack/plugins/maps/public/elasticsearch_geo_utils.test.js +++ b/x-pack/plugins/maps/public/elasticsearch_geo_utils.test.js @@ -66,7 +66,7 @@ describe('hitsToGeoJson', () => { }, }, ]; - const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point'); + const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point', []); expect(geojson.type).toBe('FeatureCollection'); expect(geojson.features.length).toBe(2); expect(geojson.features[0]).toEqual({ @@ -94,7 +94,7 @@ describe('hitsToGeoJson', () => { _source: {}, }, ]; - const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point'); + const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point', []); expect(geojson.type).toBe('FeatureCollection'); expect(geojson.features.length).toBe(1); }); @@ -111,7 +111,7 @@ describe('hitsToGeoJson', () => { }, }, ]; - const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point'); + const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point', []); expect(geojson.features.length).toBe(1); const feature = geojson.features[0]; expect(feature.properties.myField).toBe(8); @@ -128,7 +128,7 @@ describe('hitsToGeoJson', () => { }, }, ]; - const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point'); + const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point', []); expect(geojson.type).toBe('FeatureCollection'); expect(geojson.features.length).toBe(2); expect(geojson.features[0]).toEqual({ @@ -159,6 +159,23 @@ describe('hitsToGeoJson', () => { }); }); + it('Should convert epoch_millis value from string to integer', () => { + const hits = [ + { + _id: 'doc1', + _index: 'index1', + _source: { + [geoFieldName]: '20,100', + myDateField: '1587156257081', + }, + }, + ]; + const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point', ['myDateField']); + expect(geojson.type).toBe('FeatureCollection'); + expect(geojson.features.length).toBe(1); + expect(geojson.features[0].properties.myDateField).toBe(1587156257081); + }); + describe('dot in geoFieldName', () => { const indexPatternMock = { fields: { @@ -184,7 +201,7 @@ describe('hitsToGeoJson', () => { }, }, ]; - const geojson = hitsToGeoJson(hits, indexPatternFlattenHit, 'my.location', 'geo_point'); + const geojson = hitsToGeoJson(hits, indexPatternFlattenHit, 'my.location', 'geo_point', []); expect(geojson.features[0].geometry).toEqual({ coordinates: [100, 20], type: 'Point', @@ -199,7 +216,7 @@ describe('hitsToGeoJson', () => { }, }, ]; - const geojson = hitsToGeoJson(hits, indexPatternFlattenHit, 'my.location', 'geo_point'); + const geojson = hitsToGeoJson(hits, indexPatternFlattenHit, 'my.location', 'geo_point', []); expect(geojson.features[0].geometry).toEqual({ coordinates: [100, 20], type: 'Point', diff --git a/x-pack/legacy/plugins/maps/public/embeddable/README.md b/x-pack/plugins/maps/public/embeddable/README.md similarity index 100% rename from x-pack/legacy/plugins/maps/public/embeddable/README.md rename to x-pack/plugins/maps/public/embeddable/README.md diff --git a/x-pack/legacy/plugins/maps/public/embeddable/index.ts b/x-pack/plugins/maps/public/embeddable/index.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/embeddable/index.ts rename to x-pack/plugins/maps/public/embeddable/index.ts diff --git a/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable.tsx b/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx similarity index 90% rename from x-pack/legacy/plugins/maps/public/embeddable/map_embeddable.tsx rename to x-pack/plugins/maps/public/embeddable/map_embeddable.tsx index b8e4c84ad56a17..dbd48d614e99b4 100644 --- a/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable.tsx +++ b/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx @@ -9,8 +9,6 @@ import React from 'react'; import { Provider } from 'react-redux'; import { render, unmountComponentAtNode } from 'react-dom'; import 'mapbox-gl/dist/mapbox-gl.css'; - -import { I18nContext } from 'ui/i18n'; import { Subscription } from 'rxjs'; import { Unsubscribe } from 'redux'; import { @@ -18,8 +16,8 @@ import { IContainer, EmbeddableInput, EmbeddableOutput, -} from '../../../../../../src/plugins/embeddable/public'; -import { APPLY_FILTER_TRIGGER } from '../../../../../../src/plugins/ui_actions/public'; +} from '../../../../../src/plugins/embeddable/public'; +import { APPLY_FILTER_TRIGGER } from '../../../../../src/plugins/ui_actions/public'; import { esFilters, IIndexPattern, @@ -27,11 +25,9 @@ import { Filter, Query, RefreshInterval, -} from '../../../../../../src/plugins/data/public'; - +} from '../../../../../src/plugins/data/public'; import { GisMap } from '../connected_components/gis_map'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { createMapStore, MapStore } from '../../../../../plugins/maps/public/reducers/store'; +import { createMapStore, MapStore } from '../reducers/store'; import { setGotoWithCenter, replaceLayerList, @@ -45,21 +41,18 @@ import { hideViewControl, setHiddenLayers, } from '../actions/map_actions'; -import { MapCenterAndZoom } from '../../../../../plugins/maps/common/descriptor_types'; +import { MapCenterAndZoom } from '../../common/descriptor_types'; import { setReadOnly, setIsLayerTOCOpen, setOpenTOCDetails } from '../actions/ui_actions'; import { getIsLayerTOCOpen, getOpenTOCDetails } from '../selectors/ui_selectors'; import { getInspectorAdapters, setEventHandlers, EventHandlers, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../plugins/maps/public/reducers/non_serializable_instances'; +} from '../reducers/non_serializable_instances'; import { getMapCenter, getMapZoom, getHiddenLayerIds } from '../selectors/map_selectors'; import { MAP_SAVED_OBJECT_TYPE } from '../../common/constants'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { RenderToolTipContent } from '../../../../../plugins/maps/public/layers/tooltips/tooltip_property'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getUiActions } from '../../../../../plugins/maps/public/kibana_services'; +import { RenderToolTipContent } from '../layers/tooltips/tooltip_property'; +import { getUiActions, getCoreI18n } from '../kibana_services'; interface MapEmbeddableConfig { editUrl?: string; @@ -247,6 +240,8 @@ export class MapEmbeddable extends Embeddable diff --git a/x-pack/plugins/maps/public/embeddable/map_embeddable_factory.ts b/x-pack/plugins/maps/public/embeddable/map_embeddable_factory.ts new file mode 100644 index 00000000000000..a99fe63c5f3863 --- /dev/null +++ b/x-pack/plugins/maps/public/embeddable/map_embeddable_factory.ts @@ -0,0 +1,136 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import _ from 'lodash'; +import { i18n } from '@kbn/i18n'; +import { IIndexPattern } from 'src/plugins/data/public'; +// @ts-ignore +import { getMapsSavedObjectLoader } from '../angular/services/gis_map_saved_object_loader'; +import { MapEmbeddable, MapEmbeddableInput } from './map_embeddable'; +import { getIndexPatternService, getHttp, getMapsCapabilities } from '../kibana_services'; +import { + EmbeddableFactoryDefinition, + IContainer, +} from '../../../../../src/plugins/embeddable/public'; + +import { createMapPath, MAP_SAVED_OBJECT_TYPE, APP_ICON } from '../../common/constants'; + +import { createMapStore } from '../reducers/store'; +import { addLayerWithoutDataSync } from '../actions/map_actions'; +import { getQueryableUniqueIndexPatternIds } from '../selectors/map_selectors'; +import { getInitialLayers } from '../angular/get_initial_layers'; +import { mergeInputWithSavedMap } from './merge_input_with_saved_map'; + +export class MapEmbeddableFactory implements EmbeddableFactoryDefinition { + type = MAP_SAVED_OBJECT_TYPE; + savedObjectMetaData = { + name: i18n.translate('xpack.maps.mapSavedObjectLabel', { + defaultMessage: 'Map', + }), + type: MAP_SAVED_OBJECT_TYPE, + getIconForSavedObject: () => APP_ICON, + }; + + async isEditable() { + return getMapsCapabilities().save as boolean; + } + + // Not supported yet for maps types. + canCreateNew() { + return false; + } + + getDisplayName() { + return i18n.translate('xpack.maps.embeddableDisplayName', { + defaultMessage: 'map', + }); + } + + async _getIndexPatterns(layerList: unknown[]): Promise { + // Need to extract layerList from store to get queryable index pattern ids + const store = createMapStore(); + let queryableIndexPatternIds; + try { + layerList.forEach((layerDescriptor: unknown) => { + store.dispatch(addLayerWithoutDataSync(layerDescriptor)); + }); + queryableIndexPatternIds = getQueryableUniqueIndexPatternIds(store.getState()); + } catch (error) { + throw new Error( + i18n.translate('xpack.maps.mapEmbeddableFactory.invalidLayerList', { + defaultMessage: 'Unable to load map, malformed layer list', + }) + ); + } + + const promises = queryableIndexPatternIds.map(async indexPatternId => { + try { + return await getIndexPatternService().get(indexPatternId); + } catch (error) { + // Unable to load index pattern, better to not throw error so map embeddable can render + // Error will be surfaced by map embeddable since it too will be unable to locate the index pattern + return null; + } + }); + const indexPatterns = await Promise.all(promises); + return _.compact(indexPatterns) as IIndexPattern[]; + } + + async _fetchSavedMap(savedObjectId: string) { + const savedObjectLoader = getMapsSavedObjectLoader(); + return await savedObjectLoader.get(savedObjectId); + } + + createFromSavedObject = async ( + savedObjectId: string, + input: MapEmbeddableInput, + parent?: IContainer + ) => { + const savedMap = await this._fetchSavedMap(savedObjectId); + const layerList = getInitialLayers(savedMap.layerListJSON); + const indexPatterns = await this._getIndexPatterns(layerList); + + const embeddable = new MapEmbeddable( + { + layerList, + title: savedMap.title, + editUrl: getHttp().basePath.prepend(createMapPath(savedObjectId)), + indexPatterns, + editable: await this.isEditable(), + }, + input, + parent + ); + + try { + embeddable.updateInput(mergeInputWithSavedMap(input, savedMap)); + } catch (error) { + throw new Error( + i18n.translate('xpack.maps.mapEmbeddableFactory.invalidSavedObject', { + defaultMessage: 'Unable to load map, malformed saved object', + }) + ); + } + + return embeddable; + }; + + create = async (input: MapEmbeddableInput, parent?: IContainer) => { + const layerList = getInitialLayers(); + const indexPatterns = await this._getIndexPatterns(layerList); + + return new MapEmbeddable( + { + layerList, + title: input.title ?? '', + indexPatterns, + editable: false, + }, + input, + parent + ); + }; +} diff --git a/x-pack/legacy/plugins/maps/public/embeddable/merge_input_with_saved_map.d.ts b/x-pack/plugins/maps/public/embeddable/merge_input_with_saved_map.d.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/embeddable/merge_input_with_saved_map.d.ts rename to x-pack/plugins/maps/public/embeddable/merge_input_with_saved_map.d.ts diff --git a/x-pack/legacy/plugins/maps/public/embeddable/merge_input_with_saved_map.js b/x-pack/plugins/maps/public/embeddable/merge_input_with_saved_map.js similarity index 89% rename from x-pack/legacy/plugins/maps/public/embeddable/merge_input_with_saved_map.js rename to x-pack/plugins/maps/public/embeddable/merge_input_with_saved_map.js index 8e3e0a9168e30e..d91c91b3b223c9 100644 --- a/x-pack/legacy/plugins/maps/public/embeddable/merge_input_with_saved_map.js +++ b/x-pack/plugins/maps/public/embeddable/merge_input_with_saved_map.js @@ -5,8 +5,8 @@ */ import _ from 'lodash'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { DEFAULT_IS_LAYER_TOC_OPEN } from '../../../../../plugins/maps/public/reducers/ui'; + +import { DEFAULT_IS_LAYER_TOC_OPEN } from '../reducers/ui'; const MAP_EMBEDDABLE_INPUT_KEYS = [ 'hideFilterActions', diff --git a/x-pack/legacy/plugins/maps/public/feature_catalogue_entry.ts b/x-pack/plugins/maps/public/feature_catalogue_entry.ts similarity index 89% rename from x-pack/legacy/plugins/maps/public/feature_catalogue_entry.ts rename to x-pack/plugins/maps/public/feature_catalogue_entry.ts index fdda76b4e12127..6c2579bd3e4e2a 100644 --- a/x-pack/legacy/plugins/maps/public/feature_catalogue_entry.ts +++ b/x-pack/plugins/maps/public/feature_catalogue_entry.ts @@ -6,7 +6,7 @@ import { i18n } from '@kbn/i18n'; import { APP_ID, APP_ICON } from '../common/constants'; import { getAppTitle } from '../common/i18n_getters'; -import { FeatureCatalogueCategory } from '../../../../../src/plugins/home/public'; +import { FeatureCatalogueCategory } from '../../../../src/plugins/home/public'; export const featureCatalogueEntry = { id: APP_ID, diff --git a/x-pack/legacy/plugins/maps/public/help_menu_util.js b/x-pack/plugins/maps/public/help_menu_util.js similarity index 81% rename from x-pack/legacy/plugins/maps/public/help_menu_util.js rename to x-pack/plugins/maps/public/help_menu_util.js index 70b9340b562cd1..053caf66883094 100644 --- a/x-pack/legacy/plugins/maps/public/help_menu_util.js +++ b/x-pack/plugins/maps/public/help_menu_util.js @@ -3,8 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getDocLinks, getCoreChrome } from '../../../../plugins/maps/public/kibana_services'; + +import { getDocLinks, getCoreChrome } from './kibana_services'; export function addHelpMenuToAppChrome() { const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = getDocLinks(); diff --git a/x-pack/legacy/plugins/maps/public/icon.svg b/x-pack/plugins/maps/public/icon.svg similarity index 100% rename from x-pack/legacy/plugins/maps/public/icon.svg rename to x-pack/plugins/maps/public/icon.svg diff --git a/x-pack/plugins/maps/public/index.scss b/x-pack/plugins/maps/public/index.scss new file mode 100644 index 00000000000000..8b2f6d3cb61563 --- /dev/null +++ b/x-pack/plugins/maps/public/index.scss @@ -0,0 +1,17 @@ +/* GIS plugin styles */ + +// Import the EUI global scope so we can use EUI constants +@import 'src/legacy/ui/public/styles/_styling_constants'; + +// Prefix all styles with "map" to avoid conflicts. +// Examples +// mapChart +// mapChart__legend +// mapChart__legend--small +// mapChart__legend-isLoading + +@import 'main'; +@import 'mapbox_hacks'; +@import 'connected_components/index'; +@import 'components/index'; +@import 'layers/index'; diff --git a/x-pack/plugins/maps/public/layers/layer.js b/x-pack/plugins/maps/public/layers/layer.js index 19dcbaf1dfcfdc..9362ce2c028e6e 100644 --- a/x-pack/plugins/maps/public/layers/layer.js +++ b/x-pack/plugins/maps/public/layers/layer.js @@ -14,7 +14,7 @@ import { SOURCE_DATA_ID_ORIGIN, } from '../../common/constants'; import uuid from 'uuid/v4'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths + import { copyPersistentState } from '../reducers/util.js'; import { i18n } from '@kbn/i18n'; diff --git a/x-pack/plugins/maps/public/layers/sources/es_search_source/es_search_source.js b/x-pack/plugins/maps/public/layers/sources/es_search_source/es_search_source.js index 96679f0e859412..aaa56b30c735a4 100644 --- a/x-pack/plugins/maps/public/layers/sources/es_search_source/es_search_source.js +++ b/x-pack/plugins/maps/public/layers/sources/es_search_source/es_search_source.js @@ -51,7 +51,7 @@ function getDocValueAndSourceFields(indexPattern, fieldNames) { lang: field.lang, }, }; - } else if (field.readFromDocValues) { + } else if (field.type !== ES_GEO_FIELD_TYPE.GEO_SHAPE && field.readFromDocValues) { const docValueField = field.type === 'date' ? { @@ -387,11 +387,21 @@ export class ESSearchSource extends AbstractESSource { }); return properties; }; + const epochMillisFields = searchFilters.fieldNames.filter(fieldName => { + const field = getField(indexPattern, fieldName); + return field.readFromDocValues && field.type === 'date'; + }); let featureCollection; try { const geoField = await this._getGeoField(); - featureCollection = hitsToGeoJson(hits, flattenHit, geoField.name, geoField.type); + featureCollection = hitsToGeoJson( + hits, + flattenHit, + geoField.name, + geoField.type, + epochMillisFields + ); } catch (error) { throw new Error( i18n.translate('xpack.maps.source.esSearch.convertToGeoJsonErrorMsg', { diff --git a/x-pack/plugins/maps/public/layers/sources/es_source/es_source.js b/x-pack/plugins/maps/public/layers/sources/es_source/es_source.js index 3402e367cbd736..9ab87577b77806 100644 --- a/x-pack/plugins/maps/public/layers/sources/es_source/es_source.js +++ b/x-pack/plugins/maps/public/layers/sources/es_source/es_source.js @@ -16,7 +16,7 @@ import { createExtentFilter } from '../../../elasticsearch_geo_utils'; import _ from 'lodash'; import { i18n } from '@kbn/i18n'; import uuid from 'uuid/v4'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths + import { copyPersistentState } from '../../../reducers/util'; import { ES_GEO_FIELD_TYPE } from '../../../../common/constants'; import { DataRequestAbortError } from '../../util/data_request'; diff --git a/x-pack/plugins/maps/public/layers/sources/source.js b/x-pack/plugins/maps/public/layers/sources/source.js index 555b8999d62847..fd93daf249b265 100644 --- a/x-pack/plugins/maps/public/layers/sources/source.js +++ b/x-pack/plugins/maps/public/layers/sources/source.js @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { copyPersistentState } from '../../reducers/util'; import { MIN_ZOOM, MAX_ZOOM } from '../../../common/constants'; diff --git a/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js index ea521f8749d80a..8cef78f9a8f210 100644 --- a/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js +++ b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js @@ -279,6 +279,10 @@ export class DynamicStyleProperty extends AbstractStyleProperty { } getNumericalMbFeatureStateValue(value) { + if (typeof value === 'number') { + return value; + } + const valueAsFloat = parseFloat(value); return isNaN(valueAsFloat) ? null : valueAsFloat; } diff --git a/x-pack/plugins/maps/public/maps_vis_type_alias.js b/x-pack/plugins/maps/public/maps_vis_type_alias.js new file mode 100644 index 00000000000000..85613f4608c6f4 --- /dev/null +++ b/x-pack/plugins/maps/public/maps_vis_type_alias.js @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; +import { APP_ID, APP_ICON, MAP_BASE_URL } from '../common/constants'; +import { getInjectedVarFunc, getVisualizations } from './kibana_services'; + +export function getMapsVisTypeAlias() { + const showMapVisualizationTypes = getInjectedVarFunc()('showMapVisualizationTypes', false); + if (!showMapVisualizationTypes) { + getVisualizations().hideTypes(['region_map', 'tile_map']); + } + + const description = i18n.translate('xpack.maps.visTypeAlias.description', { + defaultMessage: 'Create and style maps with multiple layers and indices.', + }); + + const legacyMapVisualizationWarning = i18n.translate( + 'xpack.maps.visTypeAlias.legacyMapVizWarning', + { + defaultMessage: `Use the Maps app instead of Coordinate Map and Region Map. +The Maps app offers more functionality and is easier to use.`, + } + ); + + return { + aliasUrl: MAP_BASE_URL, + name: APP_ID, + title: i18n.translate('xpack.maps.visTypeAlias.title', { + defaultMessage: 'Maps', + }), + description: showMapVisualizationTypes + ? `${description} ${legacyMapVisualizationWarning}` + : description, + icon: APP_ICON, + stage: 'production', + }; +} diff --git a/x-pack/plugins/maps/public/plugin.ts b/x-pack/plugins/maps/public/plugin.ts index d3b9626dc83661..0b076621326ce3 100644 --- a/x-pack/plugins/maps/public/plugin.ts +++ b/x-pack/plugins/maps/public/plugin.ts @@ -33,10 +33,17 @@ import { setVisualizations, // @ts-ignore } from './kibana_services'; +import { featureCatalogueEntry } from './feature_catalogue_entry'; +// @ts-ignore +import { getMapsVisTypeAlias } from './maps_vis_type_alias'; import { registerLayerWizards } from './layers/load_layer_wizards'; +import { HomePublicPluginSetup } from '../../../../src/plugins/home/public'; +import { VisualizationsSetup } from '../../../../src/plugins/visualizations/public'; export interface MapsPluginSetupDependencies { inspector: InspectorSetupContract; + home: HomePublicPluginSetup; + visualizations: VisualizationsSetup; } // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface MapsPluginStartDependencies {} @@ -94,8 +101,15 @@ export class MapsPlugin MapsPluginStartDependencies > { public setup(core: CoreSetup, plugins: MapsPluginSetupDependencies) { - plugins.inspector.registerView(MapView); + const { inspector, home, visualizations } = plugins; + bindSetupCoreAndPlugins(core, plugins); + + inspector.registerView(MapView); + home.featureCatalogue.register(featureCatalogueEntry); + visualizations.registerAlias(getMapsVisTypeAlias()); } - public start(core: CoreStart, plugins: any) {} + public start(core: CoreStart, plugins: any) { + bindStartCoreAndPlugins(core, plugins); + } } diff --git a/x-pack/plugins/maps/public/reducers/ui.ts b/x-pack/plugins/maps/public/reducers/ui.ts index 7429545ec0e46e..f577618c74ffef 100644 --- a/x-pack/plugins/maps/public/reducers/ui.ts +++ b/x-pack/plugins/maps/public/reducers/ui.ts @@ -16,7 +16,6 @@ import { SHOW_TOC_DETAILS, HIDE_TOC_DETAILS, UPDATE_INDEXING_STAGE, - // @ts-ignore } from '../actions/ui_actions'; export enum FLYOUT_STATE { diff --git a/x-pack/legacy/plugins/maps/public/selectors/map_selectors.d.ts b/x-pack/plugins/maps/public/selectors/map_selectors.d.ts similarity index 81% rename from x-pack/legacy/plugins/maps/public/selectors/map_selectors.d.ts rename to x-pack/plugins/maps/public/selectors/map_selectors.d.ts index 8c99e0adcc14fe..32579d036590e3 100644 --- a/x-pack/legacy/plugins/maps/public/selectors/map_selectors.d.ts +++ b/x-pack/plugins/maps/public/selectors/map_selectors.d.ts @@ -6,8 +6,8 @@ import { AnyAction } from 'redux'; import { MapCenter } from '../../common/descriptor_types'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { MapStoreState } from '../../../../../plugins/maps/public/reducers/store'; + +import { MapStoreState } from '../reducers/store'; export function getHiddenLayerIds(state: MapStoreState): string[]; diff --git a/x-pack/legacy/plugins/maps/public/selectors/map_selectors.js b/x-pack/plugins/maps/public/selectors/map_selectors.js similarity index 82% rename from x-pack/legacy/plugins/maps/public/selectors/map_selectors.js rename to x-pack/plugins/maps/public/selectors/map_selectors.js index 1e710259355198..c7073efa96cd55 100644 --- a/x-pack/legacy/plugins/maps/public/selectors/map_selectors.js +++ b/x-pack/plugins/maps/public/selectors/map_selectors.js @@ -6,31 +6,27 @@ import { createSelector } from 'reselect'; import _ from 'lodash'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { TileLayer } from '../../../../../plugins/maps/public/layers/tile_layer'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { VectorTileLayer } from '../../../../../plugins/maps/public/layers/vector_tile_layer'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { VectorLayer } from '../../../../../plugins/maps/public/layers/vector_layer'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { HeatmapLayer } from '../../../../../plugins/maps/public/layers/heatmap_layer'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { BlendedVectorLayer } from '../../../../../plugins/maps/public/layers/blended_vector_layer'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getTimeFilter } from '../../../../../plugins/maps/public/kibana_services'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { TiledVectorLayer } from '../../../../../plugins/maps/public/layers/tiled_vector_layer'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getInspectorAdapters } from '../../../../../plugins/maps/public/reducers/non_serializable_instances'; -import { - copyPersistentState, - TRACKED_LAYER_DESCRIPTOR, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../plugins/maps/public/reducers/util'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { InnerJoin } from '../../../../../plugins/maps/public/layers/joins/inner_join'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getSourceByType } from '../../../../../plugins/maps/public/layers/sources/source_registry'; + +import { TileLayer } from '../layers/tile_layer'; + +import { VectorTileLayer } from '../layers/vector_tile_layer'; + +import { VectorLayer } from '../layers/vector_layer'; + +import { HeatmapLayer } from '../layers/heatmap_layer'; + +import { BlendedVectorLayer } from '../layers/blended_vector_layer'; + +import { getTimeFilter } from '../kibana_services'; + +import { getInspectorAdapters } from '../reducers/non_serializable_instances'; +import { TiledVectorLayer } from '../layers/tiled_vector_layer'; + +import { copyPersistentState, TRACKED_LAYER_DESCRIPTOR } from '../reducers/util'; + +import { InnerJoin } from '../layers/joins/inner_join'; + +import { getSourceByType } from '../layers/sources/source_registry'; function createLayerInstance(layerDescriptor, inspectorAdapters) { const source = createSourceInstance(layerDescriptor.sourceDescriptor, inspectorAdapters); diff --git a/x-pack/legacy/plugins/maps/public/selectors/map_selectors.test.js b/x-pack/plugins/maps/public/selectors/map_selectors.test.js similarity index 62% rename from x-pack/legacy/plugins/maps/public/selectors/map_selectors.test.js rename to x-pack/plugins/maps/public/selectors/map_selectors.test.js index 72cc7486175401..fec16251914ead 100644 --- a/x-pack/legacy/plugins/maps/public/selectors/map_selectors.test.js +++ b/x-pack/plugins/maps/public/selectors/map_selectors.test.js @@ -4,18 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -jest.mock('../../../../../plugins/maps/public/layers/vector_layer', () => {}); -jest.mock('../../../../../plugins/maps/public/layers/tiled_vector_layer', () => {}); -jest.mock('../../../../../plugins/maps/public/layers/blended_vector_layer', () => {}); -jest.mock('../../../../../plugins/maps/public/layers/heatmap_layer', () => {}); -jest.mock('../../../../../plugins/maps/public/layers/vector_tile_layer', () => {}); -jest.mock('../../../../../plugins/maps/public/layers/joins/inner_join', () => {}); -jest.mock('../../../../../plugins/maps/public/reducers/non_serializable_instances', () => ({ +jest.mock('../layers/vector_layer', () => {}); +jest.mock('../layers/tiled_vector_layer', () => {}); +jest.mock('../layers/blended_vector_layer', () => {}); +jest.mock('../layers/heatmap_layer', () => {}); +jest.mock('../layers/vector_tile_layer', () => {}); +jest.mock('../layers/joins/inner_join', () => {}); +jest.mock('../reducers/non_serializable_instances', () => ({ getInspectorAdapters: () => { return {}; }, })); -jest.mock('../../../../../plugins/maps/public/kibana_services', () => ({ +jest.mock('../kibana_services', () => ({ getTimeFilter: () => ({ getTime: () => { return { diff --git a/x-pack/legacy/plugins/maps/public/selectors/ui_selectors.ts b/x-pack/plugins/maps/public/selectors/ui_selectors.ts similarity index 74% rename from x-pack/legacy/plugins/maps/public/selectors/ui_selectors.ts rename to x-pack/plugins/maps/public/selectors/ui_selectors.ts index fdf2a8ea0e4f37..32d4beeb381d7f 100644 --- a/x-pack/legacy/plugins/maps/public/selectors/ui_selectors.ts +++ b/x-pack/plugins/maps/public/selectors/ui_selectors.ts @@ -4,10 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { MapStoreState } from '../../../../../plugins/maps/public/reducers/store'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { FLYOUT_STATE, INDEXING_STAGE } from '../../../../../plugins/maps/public/reducers/ui'; +import { MapStoreState } from '../reducers/store'; + +import { FLYOUT_STATE, INDEXING_STAGE } from '../reducers/ui'; export const getFlyoutDisplay = ({ ui }: MapStoreState): FLYOUT_STATE => ui.flyoutDisplay; export const getIsSetViewOpen = ({ ui }: MapStoreState): boolean => ui.isSetViewOpen; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts index 3c959b827bb1c7..fb3b2b35199477 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts @@ -52,7 +52,7 @@ export interface ClassificationAnalysis { classification: Classification; } -export interface LoadRegressionExploreDataArg { +export interface LoadExploreDataArg { filterByIsTraining?: boolean; searchQuery: SavedSearchQuery; } @@ -409,11 +409,11 @@ export function getEvalQueryBody({ ignoreDefaultQuery, }: { resultsField: string; - isTraining: boolean; + isTraining?: boolean; searchQuery?: ResultsSearchQuery; ignoreDefaultQuery?: boolean; }) { - let query; + let query: any; const trainingQuery: ResultsSearchQuery = { term: { [`${resultsField}.is_training`]: { value: isTraining } }, @@ -426,19 +426,25 @@ export function getEvalQueryBody({ searchQueryClone.bool.must = []; } - searchQueryClone.bool.must.push(trainingQuery); + if (isTraining !== undefined) { + searchQueryClone.bool.must.push(trainingQuery); + } + query = searchQueryClone; } else if (isQueryStringQuery(searchQueryClone)) { query = { bool: { - must: [searchQueryClone, trainingQuery], + must: [searchQueryClone], }, }; + if (isTraining !== undefined) { + query.bool.must.push(trainingQuery); + } } else { // Not a bool or string query so we need to create it so can add the trainingQuery query = { bool: { - must: [trainingQuery], + must: isTraining !== undefined ? [trainingQuery] : [], }, }; } @@ -456,7 +462,7 @@ interface EvaluateMetrics { } interface LoadEvalDataConfig { - isTraining: boolean; + isTraining?: boolean; index: string; dependentVariable: string; resultsField: string; @@ -535,7 +541,7 @@ interface TrackTotalHitsSearchResponse { interface LoadDocsCountConfig { ignoreDefaultQuery?: boolean; - isTraining: boolean; + isTraining?: boolean; searchQuery: SavedSearchQuery; resultsField: string; destIndex: string; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/classification_exploration_data_grid.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/classification_exploration_data_grid.tsx new file mode 100644 index 00000000000000..424fc002795caa --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/classification_exploration_data_grid.tsx @@ -0,0 +1,135 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { Dispatch, FC, SetStateAction, useCallback, useMemo } from 'react'; + +import { i18n } from '@kbn/i18n'; + +import { EuiDataGrid, EuiDataGridPaginationProps, EuiDataGridSorting } from '@elastic/eui'; + +import { euiDataGridStyle, euiDataGridToolbarSettings } from '../../../../common'; + +import { mlFieldFormatService } from '../../../../../services/field_format_service'; + +import { IndexPattern } from '../../../../../../../../../../src/plugins/data/public'; + +const PAGE_SIZE_OPTIONS = [5, 10, 25, 50]; + +type Pagination = Pick; +type TableItem = Record; + +interface ExplorationDataGridProps { + colorRange?: (d: number) => string; + columns: any[]; + indexPattern: IndexPattern; + pagination: Pagination; + resultsField: string; + rowCount: number; + selectedFields: string[]; + setPagination: Dispatch>; + setSelectedFields: Dispatch>; + setSortingColumns: Dispatch>; + sortingColumns: EuiDataGridSorting['columns']; + tableItems: TableItem[]; +} + +export const ClassificationExplorationDataGrid: FC = ({ + columns, + indexPattern, + pagination, + resultsField, + rowCount, + selectedFields, + setPagination, + setSelectedFields, + setSortingColumns, + sortingColumns, + tableItems, +}) => { + const renderCellValue = useMemo(() => { + return ({ rowIndex, columnId }: { rowIndex: number; columnId: string; setCellProps: any }) => { + const adjustedRowIndex = rowIndex - pagination.pageIndex * pagination.pageSize; + + const fullItem = tableItems[adjustedRowIndex]; + + if (fullItem === undefined) { + return null; + } + + let format: any; + + if (indexPattern !== undefined) { + format = mlFieldFormatService.getFieldFormatFromIndexPattern(indexPattern, columnId, ''); + } + + const cellValue = + fullItem.hasOwnProperty(columnId) && fullItem[columnId] !== undefined + ? fullItem[columnId] + : null; + + if (format !== undefined) { + return format.convert(cellValue, 'text'); + } + + if (typeof cellValue === 'string' || cellValue === null) { + return cellValue; + } + + if (typeof cellValue === 'boolean') { + return cellValue ? 'true' : 'false'; + } + + if (typeof cellValue === 'object' && cellValue !== null) { + return JSON.stringify(cellValue); + } + + return cellValue; + }; + }, [resultsField, rowCount, tableItems, pagination.pageIndex, pagination.pageSize]); + + const onChangeItemsPerPage = useCallback( + pageSize => { + setPagination(p => { + const pageIndex = Math.floor((p.pageSize * p.pageIndex) / pageSize); + return { pageIndex, pageSize }; + }); + }, + [setPagination] + ); + + const onChangePage = useCallback(pageIndex => setPagination(p => ({ ...p, pageIndex })), [ + setPagination, + ]); + + const onSort = useCallback(sc => setSortingColumns(sc), [setSortingColumns]); + + return ( + + ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/evaluate_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/evaluate_panel.tsx index 91dae49ba5c497..af90547606f82d 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/evaluate_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/evaluate_panel.tsx @@ -117,13 +117,7 @@ export const EvaluatePanel: FC = ({ jobConfig, jobStatus, searchQuery }) const resultsField = jobConfig.dest.results_field; let requiresKeyword = false; - const loadData = async ({ - isTrainingClause, - ignoreDefaultQuery = true, - }: { - isTrainingClause: { query: string; operator: string }; - ignoreDefaultQuery?: boolean; - }) => { + const loadData = async ({ isTraining }: { isTraining: boolean | undefined }) => { setIsLoading(true); try { @@ -134,19 +128,18 @@ export const EvaluatePanel: FC = ({ jobConfig, jobStatus, searchQuery }) } const evalData = await loadEvalData({ - isTraining: false, + isTraining, index, dependentVariable, resultsField, predictionFieldName, searchQuery, - ignoreDefaultQuery, jobType: ANALYSIS_CONFIG_TYPE.CLASSIFICATION, requiresKeyword, }); const docsCountResp = await loadDocsCount({ - isTraining: false, + isTraining, searchQuery, resultsField, destIndex: jobConfig.dest.index, @@ -225,29 +218,46 @@ export const EvaluatePanel: FC = ({ jobConfig, jobStatus, searchQuery }) }, [confusionMatrixData]); useEffect(() => { - const hasIsTrainingClause = - isResultsSearchBoolQuery(searchQuery) && - searchQuery.bool.must.filter( - (clause: any) => clause.match && clause.match[`${resultsField}.is_training`] !== undefined - ); - const isTrainingClause = - hasIsTrainingClause && - hasIsTrainingClause[0] && - hasIsTrainingClause[0].match[`${resultsField}.is_training`]; + let isTraining: boolean | undefined; + const query = + isResultsSearchBoolQuery(searchQuery) && (searchQuery.bool.should || searchQuery.bool.filter); - const noTrainingQuery = isTrainingClause === false || isTrainingClause === undefined; + if (query !== undefined && query !== false) { + for (let i = 0; i < query.length; i++) { + const clause = query[i]; - if (noTrainingQuery) { + if (clause.match && clause.match[`${resultsField}.is_training`] !== undefined) { + isTraining = clause.match[`${resultsField}.is_training`]; + break; + } else if ( + clause.bool && + (clause.bool.should !== undefined || clause.bool.filter !== undefined) + ) { + const innerQuery = clause.bool.should || clause.bool.filter; + if (innerQuery !== undefined) { + for (let j = 0; j < innerQuery.length; j++) { + const innerClause = innerQuery[j]; + if ( + innerClause.match && + innerClause.match[`${resultsField}.is_training`] !== undefined + ) { + isTraining = innerClause.match[`${resultsField}.is_training`]; + break; + } + } + } + } + } + } + if (isTraining === undefined) { setDataSubsetTitle(SUBSET_TITLE.ENTIRE); } else { setDataSubsetTitle( - isTrainingClause && isTrainingClause.query === 'true' - ? SUBSET_TITLE.TRAINING - : SUBSET_TITLE.TESTING + isTraining && isTraining === true ? SUBSET_TITLE.TRAINING : SUBSET_TITLE.TESTING ); } - loadData({ isTrainingClause }); + loadData({ isTraining }); }, [JSON.stringify(searchQuery)]); const renderCellValue = ({ diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/results_table.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/results_table.tsx index 9758dd969b443f..bf63dfe68fe9e5 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/results_table.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/results_table.tsx @@ -4,71 +4,39 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Fragment, FC, useEffect, useState } from 'react'; -import moment from 'moment-timezone'; - +import React, { Fragment, FC, useEffect } from 'react'; import { i18n } from '@kbn/i18n'; import { - EuiBadge, - EuiButtonIcon, EuiCallOut, - EuiCheckbox, EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiPanel, - EuiPopover, - EuiPopoverTitle, EuiProgress, EuiSpacer, EuiText, - EuiToolTip, - Query, } from '@elastic/eui'; -import { Query as QueryType } from '../../../analytics_management/components/analytics_list/common'; -import { ES_FIELD_TYPES } from '../../../../../../../../../../src/plugins/data/public'; -import { mlFieldFormatService } from '../../../../../services/field_format_service'; import { IndexPattern } from '../../../../../../../../../../src/plugins/data/public'; - -import { - ColumnType, - mlInMemoryTableBasicFactory, - OnTableChangeArg, - SortingPropType, - SORT_DIRECTION, -} from '../../../../../components/ml_in_memory_table'; - -import { formatHumanReadableDateTimeSeconds } from '../../../../../util/date_utils'; -import { Field } from '../../../../../../../common/types/fields'; -import { SavedSearchQuery } from '../../../../../contexts/ml'; import { BASIC_NUMERICAL_TYPES, EXTENDED_NUMERICAL_TYPES, - isKeywordAndTextType, sortRegressionResultsFields, } from '../../../../common/fields'; import { - toggleSelectedField, - EsDoc, DataFrameAnalyticsConfig, - EsFieldName, MAX_COLUMNS, - getPredictedFieldName, INDEX_STATUS, SEARCH_SIZE, defaultSearchQuery, - getDependentVar, } from '../../../../common'; import { getTaskStateBadge } from '../../../analytics_management/components/analytics_list/columns'; import { DATA_FRAME_TASK_STATE } from '../../../analytics_management/components/analytics_list/common'; -import { useExploreData, TableItem } from './use_explore_data'; +import { useExploreData } from './use_explore_data'; // TableItem import { ExplorationTitle } from './classification_exploration'; - -const PAGE_SIZE_OPTIONS = [5, 10, 25, 50]; - -const MlInMemoryTableBasic = mlInMemoryTableBasicFactory(); +import { ClassificationExplorationDataGrid } from './classification_exploration_data_grid'; +import { ExplorationQueryBar } from '../exploration_query_bar'; const showingDocs = i18n.translate( 'xpack.ml.dataframe.analytics.classificationExploration.documentsShownHelpText', @@ -94,307 +62,65 @@ interface Props { export const ResultsTable: FC = React.memo( ({ indexPattern, jobConfig, jobStatus, setEvaluateSearchQuery }) => { - const [pageIndex, setPageIndex] = useState(0); - const [pageSize, setPageSize] = useState(25); - const [selectedFields, setSelectedFields] = useState([] as Field[]); - const [docFields, setDocFields] = useState([] as Field[]); - const [depVarType, setDepVarType] = useState(undefined); - const [isColumnsPopoverVisible, setColumnsPopoverVisible] = useState(false); - const [searchQuery, setSearchQuery] = useState(defaultSearchQuery); - const [searchError, setSearchError] = useState(undefined); - const [searchString, setSearchString] = useState(undefined); - - const predictedFieldName = getPredictedFieldName( - jobConfig.dest.results_field, - jobConfig.analysis - ); - - const dependentVariable = getDependentVar(jobConfig.analysis); - - function toggleColumnsPopover() { - setColumnsPopoverVisible(!isColumnsPopoverVisible); - } - - function closeColumnsPopover() { - setColumnsPopoverVisible(false); - } - - function toggleColumn(column: EsFieldName) { - if (tableItems.length > 0 && jobConfig !== undefined) { - // spread to a new array otherwise the component wouldn't re-render - setSelectedFields([ - ...toggleSelectedField(selectedFields, column, jobConfig.dest.results_field, depVarType), - ]); - } - } - const needsDestIndexFields = indexPattern && indexPattern.title === jobConfig.source.index[0]; - + const resultsField = jobConfig.dest.results_field; const { errorMessage, - loadExploreData, - sortField, - sortDirection, - status, - tableItems, - } = useExploreData( - jobConfig, - needsDestIndexFields, + fieldTypes, + pagination, + searchQuery, selectedFields, + rowCount, + setPagination, + setSearchQuery, setSelectedFields, - setDocFields, - setDepVarType - ); + setSortingColumns, + sortingColumns, + status, + tableFields, + tableItems, + } = useExploreData(jobConfig, needsDestIndexFields); - const columns: Array> = selectedFields - .sort(({ name: a }, { name: b }) => sortRegressionResultsFields(a, b, jobConfig)) - .map(field => { - const { type } = field; - let format: any; + useEffect(() => { + setEvaluateSearchQuery(searchQuery); + }, [JSON.stringify(searchQuery)]); - if (indexPattern !== undefined) { - format = mlFieldFormatService.getFieldFormatFromIndexPattern(indexPattern, field.id, ''); - } + const columns = tableFields + .sort((a: any, b: any) => sortRegressionResultsFields(a, b, jobConfig)) + .map((field: any) => { + // Built-in values are ['boolean', 'currency', 'datetime', 'numeric', 'json'] + // To fall back to the default string schema it needs to be undefined. + let schema; + let isSortable = true; + const type = fieldTypes[field]; const isNumber = type !== undefined && (BASIC_NUMERICAL_TYPES.has(type) || EXTENDED_NUMERICAL_TYPES.has(type)); - const column: ColumnType = { - field: field.name, - name: field.name, - sortable: true, - truncateText: true, - }; - - const render = (d: any, fullItem: EsDoc) => { - if (format !== undefined) { - d = format.convert(d, 'text'); - return d; - } - - if (Array.isArray(d) && d.every(item => typeof item === 'string')) { - // If the cells data is an array of strings, return as a comma separated list. - // The list will get limited to 5 items with `…` at the end if there's more in the original array. - return `${d.slice(0, 5).join(', ')}${d.length > 5 ? ', …' : ''}`; - } else if (Array.isArray(d)) { - // If the cells data is an array of e.g. objects, display a 'array' badge with a - // tooltip that explains that this type of field is not supported in this table. - return ( - - - {i18n.translate( - 'xpack.ml.dataframe.analytics.classificationExploration.indexArrayBadgeContent', - { - defaultMessage: 'array', - } - )} - - - ); - } - - return d; - }; - if (isNumber) { - column.dataType = 'number'; - column.render = render; - } else if (typeof type !== 'undefined') { - switch (type) { - case ES_FIELD_TYPES.BOOLEAN: - column.dataType = ES_FIELD_TYPES.BOOLEAN; - column.render = d => (d ? 'true' : 'false'); - break; - case ES_FIELD_TYPES.DATE: - column.align = 'right'; - if (format !== undefined) { - column.render = render; - } else { - column.render = (d: any) => { - if (d !== undefined) { - return formatHumanReadableDateTimeSeconds(moment(d).unix() * 1000); - } - return d; - }; - } - break; - default: - column.render = render; - break; - } - } else { - column.render = render; + schema = 'numeric'; } - return column; - }); - - const docFieldsCount = docFields.length; - - useEffect(() => { - if ( - jobConfig !== undefined && - columns.length > 0 && - selectedFields.length > 0 && - sortField !== undefined && - sortDirection !== undefined && - selectedFields.some(field => field.name === sortField) - ) { - let field = sortField; - // If sorting by predictedField use dependentVar type - if (predictedFieldName === sortField) { - field = dependentVariable; + switch (type) { + case 'date': + schema = 'datetime'; + break; + case 'geo_point': + schema = 'json'; + break; + case 'boolean': + schema = 'boolean'; + break; } - const requiresKeyword = isKeywordAndTextType(field); - - loadExploreData({ - field: sortField, - direction: sortDirection, - searchQuery, - requiresKeyword, - }); - } - }, [JSON.stringify(searchQuery)]); - - useEffect(() => { - // By default set sorting to descending on the prediction field (`_prediction`). - // if that's not available sort ascending on the first column. Check if the current sorting field is still available. - if ( - jobConfig !== undefined && - columns.length > 0 && - selectedFields.length > 0 && - !selectedFields.some(field => field.name === sortField) - ) { - const predictedFieldSelected = selectedFields.some( - field => field.name === predictedFieldName - ); - - // CHECK IF keyword suffix is needed (if predicted field is selected we have to check the dependent variable type) - let sortByField = predictedFieldSelected ? dependentVariable : selectedFields[0].name; - - const requiresKeyword = isKeywordAndTextType(sortByField); - - sortByField = predictedFieldSelected ? predictedFieldName : sortByField; - - const direction = predictedFieldSelected ? SORT_DIRECTION.DESC : SORT_DIRECTION.ASC; - loadExploreData({ field: sortByField, direction, searchQuery, requiresKeyword }); - } - }, [ - jobConfig, - columns.length, - selectedFields.length, - sortField, - sortDirection, - tableItems.length, - ]); - - let sorting: SortingPropType = false; - let onTableChange; - - if (columns.length > 0 && sortField !== '' && sortField !== undefined) { - sorting = { - sort: { - field: sortField, - direction: sortDirection, - }, - }; - - onTableChange = ({ - page = { index: 0, size: 10 }, - sort = { field: sortField, direction: sortDirection }, - }: OnTableChangeArg) => { - const { index, size } = page; - setPageIndex(index); - setPageSize(size); - if (sort.field !== sortField || sort.direction !== sortDirection) { - let field = sort.field; - // If sorting by predictedField use depVar for type check - if (predictedFieldName === sort.field) { - field = dependentVariable; - } - - loadExploreData({ - ...sort, - searchQuery, - requiresKeyword: isKeywordAndTextType(field), - }); + if (field === `${resultsField}.feature_importance`) { + isSortable = false; } - }; - } - const pagination = { - initialPageIndex: pageIndex, - initialPageSize: pageSize, - totalItemCount: tableItems.length, - pageSizeOptions: PAGE_SIZE_OPTIONS, - hidePerPageOptions: false, - }; - - const onQueryChange = ({ query, error }: { query: QueryType; error: any }) => { - if (error) { - setSearchError(error.message); - } else { - try { - const esQueryDsl = Query.toESQuery(query); - setSearchQuery(esQueryDsl); - setSearchString(query.text); - setSearchError(undefined); - // set query for use in evaluate panel - setEvaluateSearchQuery(esQueryDsl); - } catch (e) { - setSearchError(e.toString()); - } - } - }; + return { id: field, schema, isSortable }; + }); - const search = { - onChange: onQueryChange, - defaultQuery: searchString, - box: { - incremental: false, - placeholder: i18n.translate( - 'xpack.ml.dataframe.analytics.regressionExploration.searchBoxPlaceholder', - { - defaultMessage: 'E.g. avg>0.5', - } - ), - }, - filters: [ - { - type: 'field_value_toggle_group', - field: `${jobConfig.dest.results_field}.is_training`, - items: [ - { - value: false, - name: i18n.translate( - 'xpack.ml.dataframe.analytics.regressionExploration.isTestingLabel', - { - defaultMessage: 'Testing', - } - ), - }, - { - value: true, - name: i18n.translate( - 'xpack.ml.dataframe.analytics.regressionExploration.isTrainingLabel', - { - defaultMessage: 'Training', - } - ), - }, - ], - }, - ], - }; + const docFieldsCount = tableFields.length; if (jobConfig === undefined) { return null; @@ -426,11 +152,6 @@ export const ResultsTable: FC = React.memo( ); } - const tableError = - status === INDEX_STATUS.ERROR && errorMessage.includes('parsing_exception') - ? errorMessage - : searchError; - return ( = React.memo( {docFieldsCount > MAX_COLUMNS && ( {i18n.translate( - 'xpack.ml.dataframe.analytics.regressionExploration.fieldSelection', + 'xpack.ml.dataframe.analytics.classificationExploration.fieldSelection', { defaultMessage: '{selectedFieldsLength, number} of {docFieldsCount, number} {docFieldsCount, plural, one {field} other {fields}} selected', @@ -466,52 +187,6 @@ export const ResultsTable: FC = React.memo( )}
- - - - } - isOpen={isColumnsPopoverVisible} - closePopover={closeColumnsPopover} - ownFocus - > - - {i18n.translate( - 'xpack.ml.dataframe.analytics.regressionExploration.selectFieldsPopoverTitle', - { - defaultMessage: 'Select fields', - } - )} - -
- {docFields.map(({ name }) => ( - field.name === name)} - onChange={() => toggleColumn(name)} - disabled={ - selectedFields.some(field => field.name === name) && - selectedFields.length === 1 - } - /> - ))} -
-
-
-
@@ -520,28 +195,39 @@ export const ResultsTable: FC = React.memo( )} {(columns.length > 0 || searchQuery !== defaultSearchQuery) && ( - - - - - - - + + + + + + + + + + + + + + + + )} ); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/use_explore_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/use_explore_data.ts index 9527a9adb98ced..c8809ca5e471bd 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/use_explore_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/use_explore_data.ts @@ -3,113 +3,158 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import React, { useEffect, useState } from 'react'; +import { useEffect, useState, Dispatch, SetStateAction } from 'react'; +import { EuiDataGridPaginationProps, EuiDataGridSorting } from '@elastic/eui'; import { SearchResponse } from 'elasticsearch'; import { cloneDeep } from 'lodash'; -import { SortDirection, SORT_DIRECTION } from '../../../../../components/ml_in_memory_table'; +import { SORT_DIRECTION } from '../../../../../components/ml_in_memory_table'; import { ml } from '../../../../../services/ml_api_service'; import { getNestedProperty } from '../../../../../util/object_utils'; import { newJobCapsService } from '../../../../../services/new_job_capabilities_service'; -import { Field } from '../../../../../../../common/types/fields'; +import { isKeywordAndTextType } from '../../../../common/fields'; +import { Dictionary } from '../../../../../../../common/types/common'; import { ES_FIELD_TYPES } from '../../../../../../../../../../src/plugins/data/public'; import { defaultSearchQuery, ResultsSearchQuery, isResultsSearchBoolQuery, + LoadExploreDataArg, } from '../../../../common/analytics'; import { getDefaultFieldsFromJobCaps, + getDependentVar, getFlattenedFields, + getPredictedFieldName, DataFrameAnalyticsConfig, EsFieldName, INDEX_STATUS, - SEARCH_SIZE, - SearchQuery, } from '../../../../common'; import { SavedSearchQuery } from '../../../../../contexts/ml'; -interface LoadClassificationExploreDataArg { - direction: SortDirection; - filterByIsTraining?: boolean; - field: string; - searchQuery: SavedSearchQuery; - requiresKeyword?: boolean; - pageIndex?: number; - pageSize?: number; -} - export type TableItem = Record; +type Pagination = Pick; export interface UseExploreDataReturnType { errorMessage: string; - loadExploreData: (arg: LoadClassificationExploreDataArg) => void; - sortField: EsFieldName; - sortDirection: SortDirection; + fieldTypes: { [key: string]: ES_FIELD_TYPES }; + pagination: Pagination; + rowCount: number; + searchQuery: SavedSearchQuery; + selectedFields: EsFieldName[]; + setFilterByIsTraining: Dispatch>; + setPagination: Dispatch>; + setSearchQuery: Dispatch>; + setSelectedFields: Dispatch>; + setSortingColumns: Dispatch>; + sortingColumns: EuiDataGridSorting['columns']; status: INDEX_STATUS; + tableFields: string[]; tableItems: TableItem[]; } +type EsSorting = Dictionary<{ + order: 'asc' | 'desc'; +}>; + +// The types specified in `@types/elasticsearch` are out of date and still have `total: number`. +interface SearchResponse7 extends SearchResponse { + hits: SearchResponse['hits'] & { + total: { + value: number; + relation: string; + }; + }; +} + export const useExploreData = ( - jobConfig: DataFrameAnalyticsConfig | undefined, - needsDestIndexFields: boolean, - selectedFields: Field[], - setSelectedFields: React.Dispatch>, - setDocFields: React.Dispatch>, - setDepVarType: React.Dispatch> + jobConfig: DataFrameAnalyticsConfig, + needsDestIndexFields: boolean ): UseExploreDataReturnType => { const [errorMessage, setErrorMessage] = useState(''); const [status, setStatus] = useState(INDEX_STATUS.UNUSED); + + const [selectedFields, setSelectedFields] = useState([] as EsFieldName[]); + const [tableFields, setTableFields] = useState([]); const [tableItems, setTableItems] = useState([]); - const [sortField, setSortField] = useState(''); - const [sortDirection, setSortDirection] = useState(SORT_DIRECTION.ASC); + const [fieldTypes, setFieldTypes] = useState<{ [key: string]: ES_FIELD_TYPES }>({}); + const [rowCount, setRowCount] = useState(0); + + const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 25 }); + const [searchQuery, setSearchQuery] = useState(defaultSearchQuery); + const [filterByIsTraining, setFilterByIsTraining] = useState(undefined); + const [sortingColumns, setSortingColumns] = useState([]); + + const predictedFieldName = getPredictedFieldName( + jobConfig.dest.results_field, + jobConfig.analysis + ); + const dependentVariable = getDependentVar(jobConfig.analysis); const getDefaultSelectedFields = () => { const { fields } = newJobCapsService; - if (selectedFields.length === 0 && jobConfig !== undefined) { - const { - selectedFields: defaultSelected, - docFields, - depVarType, - } = getDefaultFieldsFromJobCaps(fields, jobConfig, needsDestIndexFields); - - setDepVarType(depVarType); - setSelectedFields(defaultSelected); - setDocFields(docFields); + const { selectedFields: defaultSelected, docFields } = getDefaultFieldsFromJobCaps( + fields, + jobConfig, + needsDestIndexFields + ); + + const types: { [key: string]: ES_FIELD_TYPES } = {}; + const allFields: string[] = []; + + docFields.forEach(field => { + types[field.id] = field.type; + allFields.push(field.id); + }); + + setFieldTypes(types); + setSelectedFields(defaultSelected.map(field => field.id)); + setTableFields(allFields); } }; const loadExploreData = async ({ - field, - direction, - searchQuery, - requiresKeyword, - }: LoadClassificationExploreDataArg) => { + filterByIsTraining: isTraining, + searchQuery: incomingQuery, + }: LoadExploreDataArg) => { if (jobConfig !== undefined) { setErrorMessage(''); setStatus(INDEX_STATUS.LOADING); try { const resultsField = jobConfig.dest.results_field; - const searchQueryClone: ResultsSearchQuery = cloneDeep(searchQuery); + const searchQueryClone: ResultsSearchQuery = cloneDeep(incomingQuery); let query: ResultsSearchQuery; + const { pageIndex, pageSize } = pagination; + // If filterByIsTraining is defined - add that in to the final query + const trainingQuery = + isTraining !== undefined + ? { + term: { [`${resultsField}.is_training`]: { value: isTraining } }, + } + : undefined; - if (JSON.stringify(searchQuery) === JSON.stringify(defaultSearchQuery)) { - query = { + if (JSON.stringify(incomingQuery) === JSON.stringify(defaultSearchQuery)) { + const existsQuery = { exists: { field: resultsField, }, }; + + query = { + bool: { + must: [existsQuery], + }, + }; + + if (trainingQuery !== undefined && isResultsSearchBoolQuery(query)) { + query.bool.must.push(trainingQuery); + } } else if (isResultsSearchBoolQuery(searchQueryClone)) { if (searchQueryClone.bool.must === undefined) { searchQueryClone.bool.must = []; @@ -121,33 +166,37 @@ export const useExploreData = ( }, }); + if (trainingQuery !== undefined) { + searchQueryClone.bool.must.push(trainingQuery); + } + query = searchQueryClone; } else { query = searchQueryClone; } - const body: SearchQuery = { - query, - }; - - if (field !== undefined) { - body.sort = [ - { - [`${field}${requiresKeyword ? '.keyword' : ''}`]: { - order: direction, - }, - }, - ]; - } + const sort: EsSorting = sortingColumns + .map(column => { + const { id } = column; + column.id = isKeywordAndTextType(id) ? `${id}.keyword` : id; + return column; + }) + .reduce((s, column) => { + s[column.id] = { order: column.direction }; + return s; + }, {} as EsSorting); - const resp: SearchResponse = await ml.esSearch({ + const resp: SearchResponse7 = await ml.esSearch({ index: jobConfig.dest.index, - size: SEARCH_SIZE, - body, + body: { + query, + from: pageIndex * pageSize, + size: pageSize, + ...(Object.keys(sort).length > 0 ? { sort } : {}), + }, }); - setSortField(field); - setSortDirection(direction); + setRowCount(resp.hits.total.value); const docs = resp.hits.hits; @@ -199,10 +248,45 @@ export const useExploreData = ( }; useEffect(() => { - if (jobConfig !== undefined) { - getDefaultSelectedFields(); - } + getDefaultSelectedFields(); + }, [jobConfig && jobConfig.id]); + + // By default set sorting to descending on the prediction field (`_prediction`). + useEffect(() => { + const sortByField = isKeywordAndTextType(dependentVariable) + ? `${predictedFieldName}.keyword` + : predictedFieldName; + const direction = SORT_DIRECTION.DESC; + + setSortingColumns([{ id: sortByField, direction }]); }, [jobConfig && jobConfig.id]); - return { errorMessage, loadExploreData, sortField, sortDirection, status, tableItems }; + useEffect(() => { + loadExploreData({ filterByIsTraining, searchQuery }); + }, [ + filterByIsTraining, + jobConfig && jobConfig.id, + pagination, + searchQuery, + selectedFields, + sortingColumns, + ]); + + return { + errorMessage, + fieldTypes, + pagination, + searchQuery, + selectedFields, + rowCount, + setFilterByIsTraining, + setPagination, + setSelectedFields, + setSortingColumns, + setSearchQuery, + sortingColumns, + status, + tableItems, + tableFields, + }; }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/use_explore_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/use_explore_data.ts index c68fe5b2cbee86..978aafd10de11f 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/use_explore_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/use_explore_data.ts @@ -29,7 +29,7 @@ import { Dictionary } from '../../../../../../../common/types/common'; import { isKeywordAndTextType } from '../../../../common/fields'; import { ES_FIELD_TYPES } from '../../../../../../../../../../src/plugins/data/public'; import { - LoadRegressionExploreDataArg, + LoadExploreDataArg, defaultSearchQuery, ResultsSearchQuery, isResultsSearchBoolQuery, @@ -120,7 +120,7 @@ export const useExploreData = ( const loadExploreData = async ({ filterByIsTraining: isTraining, searchQuery: incomingQuery, - }: LoadRegressionExploreDataArg) => { + }: LoadExploreDataArg) => { if (jobConfig !== undefined) { setErrorMessage(''); setStatus(INDEX_STATUS.LOADING); diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js index 5e505757dd2aa3..42742f6efcb2a5 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js @@ -150,7 +150,7 @@ function getTimeseriesexplorerDefaultState() { }; } -const containerPadding = 24; +const containerPadding = 34; export class TimeSeriesExplorer extends React.Component { static propTypes = { diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.test.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.test.ts index 1a9f2a4da32c20..f0ad6399c6c72d 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.test.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.test.ts @@ -182,7 +182,6 @@ describe('get_all_stats', () => { }, { logger: coreMock.createPluginInitializerContext().logger.get('test'), - isDev: true, version: 'version', maxBucketSize: 1, } @@ -208,7 +207,6 @@ describe('get_all_stats', () => { }, { logger: coreMock.createPluginInitializerContext().logger.get('test'), - isDev: true, version: 'version', maxBucketSize: 1, } diff --git a/x-pack/plugins/reporting/server/config/schema.ts b/x-pack/plugins/reporting/server/config/schema.ts index 67d70c1513c15d..402fddcb5e0146 100644 --- a/x-pack/plugins/reporting/server/config/schema.ts +++ b/x-pack/plugins/reporting/server/config/schema.ts @@ -114,6 +114,7 @@ const CaptureSchema = schema.object({ const CsvSchema = schema.object({ checkForFormulas: schema.boolean({ defaultValue: true }), + escapeFormulaValues: schema.boolean({ defaultValue: false }), enablePanelActionDownload: schema.boolean({ defaultValue: true }), maxSizeBytes: schema.number({ defaultValue: 1024 * 1024 * 10, // 10MB diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/rules/validate.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/rules/validate.ts index c207d075331b6e..cfba40fc225a24 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/rules/validate.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/rules/validate.ts @@ -9,8 +9,9 @@ import { fold } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; import * as t from 'io-ts'; +import { formatErrors } from '../../../../utils/build_validation/format_errors'; +import { exactCheck } from '../../../../utils/build_validation/exact_check'; import { PartialAlert, FindResult } from '../../../../../../alerting/server'; -import { formatErrors } from '../schemas/response/utils'; import { isAlertType, IRuleSavedAttributesSavedObjectAttributes, @@ -19,7 +20,6 @@ import { import { OutputRuleAlertRest } from '../../types'; import { createBulkErrorObject, BulkError } from '../utils'; import { rulesSchema, RulesSchema } from '../schemas/response/rules_schema'; -import { exactCheck } from '../schemas/response/exact_check'; import { transformFindAlerts, transform, transformAlertToRule } from './utils'; import { findRulesSchema } from '../schemas/response/find_rules_schema'; import { RuleActions } from '../../rule_actions/types'; diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/__mocks__/utils.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/__mocks__/utils.ts index 21f18f9db55fba..fef6bcf42e49f0 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/__mocks__/utils.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/__mocks__/utils.ts @@ -4,32 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import * as t from 'io-ts'; -import { fold } from 'fp-ts/lib/Either'; import { RulesSchema } from '../rules_schema'; import { RulesBulkSchema } from '../rules_bulk_schema'; import { ErrorSchema } from '../error_schema'; import { FindRulesSchema } from '../find_rules_schema'; -import { formatErrors } from '../utils'; -import { pipe } from 'fp-ts/lib/pipeable'; - -interface Message { - errors: t.Errors; - schema: T | {}; -} - -const onLeft = (errors: t.Errors): Message => { - return { schema: {}, errors }; -}; - -const onRight = (schema: T): Message => { - return { - schema, - errors: [], - }; -}; - -export const foldLeftRight = fold(onLeft, onRight); export const ANCHOR_DATE = '2020-02-20T03:57:54.037Z'; @@ -127,18 +105,3 @@ export const getFindResponseSingle = (): FindRulesSchema => ({ total: 1, data: [getBaseResponsePayload()], }); - -/** - * Convenience utility to keep the error message handling within tests to be - * very concise. - * @param validation The validation to get the errors from - */ -export const getPaths = (validation: t.Validation): string[] => { - return pipe( - validation, - fold( - errors => formatErrors(errors), - () => ['no errors'] - ) - ); -}; diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/check_type_dependents.test.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/check_type_dependents.test.ts index 0eda2a7a13d96f..fbd2382e2826d4 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/check_type_dependents.test.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/check_type_dependents.test.ts @@ -15,17 +15,13 @@ import { addQueryFields, addMlFields, } from './check_type_dependents'; -import { - foldLeftRight, - getBaseResponsePayload, - getPaths, - getMlRuleResponsePayload, -} from './__mocks__/utils'; +import { getBaseResponsePayload, getMlRuleResponsePayload } from './__mocks__/utils'; import { left } from 'fp-ts/lib/Either'; -import { exactCheck } from './exact_check'; import { RulesSchema } from './rules_schema'; import { TypeAndTimelineOnly } from './type_timeline_only_schema'; import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags'; +import { foldLeftRight, getPaths } from '../../../../../utils/build_validation/__mocks__/utils'; +import { exactCheck } from '../../../../../utils/build_validation/exact_check'; describe('check_type_dependents', () => { beforeAll(() => { diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/error_schema.test.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/error_schema.test.ts index 11d8b85f259206..6e159a792edb66 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/error_schema.test.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/error_schema.test.ts @@ -7,10 +7,11 @@ import { left } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; -import { exactCheck } from './exact_check'; -import { foldLeftRight, getErrorPayload, getPaths } from './__mocks__/utils'; +import { getErrorPayload } from './__mocks__/utils'; import { errorSchema, ErrorSchema } from './error_schema'; import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags'; +import { exactCheck } from '../../../../../utils/build_validation/exact_check'; +import { foldLeftRight, getPaths } from '../../../../../utils/build_validation/__mocks__/utils'; describe('error_schema', () => { beforeAll(() => { diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/find_rules_schema.test.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/find_rules_schema.test.ts index f5c1970ee8c55c..68b67db595d76d 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/find_rules_schema.test.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/find_rules_schema.test.ts @@ -5,17 +5,13 @@ */ import { findRulesSchema, FindRulesSchema } from './find_rules_schema'; -import { exactCheck } from './exact_check'; import { pipe } from 'fp-ts/lib/pipeable'; -import { - foldLeftRight, - getFindResponseSingle, - getBaseResponsePayload, - getPaths, -} from './__mocks__/utils'; +import { getFindResponseSingle, getBaseResponsePayload } from './__mocks__/utils'; import { left } from 'fp-ts/lib/Either'; import { RulesSchema } from './rules_schema'; import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags'; +import { getPaths, foldLeftRight } from '../../../../../utils/build_validation/__mocks__/utils'; +import { exactCheck } from '../../../../../utils/build_validation/exact_check'; describe('find_rules_schema', () => { beforeAll(() => { diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/import_rules_schema.test.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/import_rules_schema.test.ts index ce4bbf420a634b..b0b863ebbbc0b2 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/import_rules_schema.test.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/import_rules_schema.test.ts @@ -4,13 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { exactCheck } from './exact_check'; import { pipe } from 'fp-ts/lib/pipeable'; -import { foldLeftRight, getPaths } from './__mocks__/utils'; -import { left } from 'fp-ts/lib/Either'; +import { left, Either } from 'fp-ts/lib/Either'; import { ImportRulesSchema, importRulesSchema } from './import_rules_schema'; import { ErrorSchema } from './error_schema'; import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags'; +import { exactCheck } from '../../../../../utils/build_validation/exact_check'; +import { getPaths, foldLeftRight } from '../../../../../utils/build_validation/__mocks__/utils'; +import { Errors } from 'io-ts'; describe('import_rules_schema', () => { beforeAll(() => { @@ -79,13 +80,31 @@ describe('import_rules_schema', () => { }); test('it should NOT validate a success that is not a boolean', () => { + type UnsafeCastForTest = Either< + Errors, + { + success: string; + success_count: number; + errors: Array< + { + id?: string | undefined; + rule_id?: string | undefined; + } & { + error: { + status_code: number; + message: string; + }; + } + >; + } + >; const payload: Omit & { success: string } = { success: 'hello', success_count: 0, errors: [], }; const decoded = importRulesSchema.decode(payload); - const checked = exactCheck(payload, decoded); + const checked = exactCheck(payload, decoded as UnsafeCastForTest); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "hello" supplied to "success"']); diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/prepackaged_rules_schema.test.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/prepackaged_rules_schema.test.ts index 46667826416e1f..827167c63fd58e 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/prepackaged_rules_schema.test.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/prepackaged_rules_schema.test.ts @@ -4,12 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { exactCheck } from './exact_check'; import { pipe } from 'fp-ts/lib/pipeable'; -import { foldLeftRight, getPaths } from './__mocks__/utils'; import { left } from 'fp-ts/lib/Either'; import { PrePackagedRulesSchema, prePackagedRulesSchema } from './prepackaged_rules_schema'; import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags'; +import { exactCheck } from '../../../../../utils/build_validation/exact_check'; +import { foldLeftRight, getPaths } from '../../../../../utils/build_validation/__mocks__/utils'; describe('prepackaged_rules_schema', () => { beforeAll(() => { diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/prepackaged_rules_status_schema.test.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/prepackaged_rules_status_schema.test.ts index 1c270ff402f75e..a864667583c0a8 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/prepackaged_rules_status_schema.test.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/prepackaged_rules_status_schema.test.ts @@ -4,15 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -import { exactCheck } from './exact_check'; import { pipe } from 'fp-ts/lib/pipeable'; -import { foldLeftRight, getPaths } from './__mocks__/utils'; import { left } from 'fp-ts/lib/Either'; import { PrePackagedRulesStatusSchema, prePackagedRulesStatusSchema, } from './prepackaged_rules_status_schema'; import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags'; +import { exactCheck } from '../../../../../utils/build_validation/exact_check'; +import { foldLeftRight, getPaths } from '../../../../../utils/build_validation/__mocks__/utils'; describe('prepackaged_rules_schema', () => { beforeAll(() => { diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/rules_bulk_schema.test.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/rules_bulk_schema.test.ts index 8dc97d727c4d1d..9a7cf5e2c2871c 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/rules_bulk_schema.test.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/rules_bulk_schema.test.ts @@ -7,17 +7,13 @@ import { left } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; -import { exactCheck } from './exact_check'; -import { - foldLeftRight, - getBaseResponsePayload, - getErrorPayload, - getPaths, -} from './__mocks__/utils'; +import { getBaseResponsePayload, getErrorPayload } from './__mocks__/utils'; import { RulesBulkSchema, rulesBulkSchema } from './rules_bulk_schema'; import { RulesSchema } from './rules_schema'; import { ErrorSchema } from './error_schema'; import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags'; +import { exactCheck } from '../../../../../utils/build_validation/exact_check'; +import { foldLeftRight, getPaths } from '../../../../../utils/build_validation/__mocks__/utils'; describe('prepackaged_rule_schema', () => { beforeAll(() => { diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/rules_schema.test.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/rules_schema.test.ts index 4bfc51c1a66aab..82a6682e6461f9 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/rules_schema.test.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/rules_schema.test.ts @@ -7,10 +7,11 @@ import { left } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; -import { exactCheck } from './exact_check'; import { rulesSchema, RulesSchema, removeList } from './rules_schema'; -import { foldLeftRight, getBaseResponsePayload, getPaths } from './__mocks__/utils'; +import { getBaseResponsePayload } from './__mocks__/utils'; import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags'; +import { exactCheck } from '../../../../../utils/build_validation/exact_check'; +import { foldLeftRight, getPaths } from '../../../../../utils/build_validation/__mocks__/utils'; export const ANCHOR_DATE = '2020-02-20T03:57:54.037Z'; diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/type_timeline_only_schema.test.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/type_timeline_only_schema.test.ts index 68a3c8b3038239..85fb124464487a 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/type_timeline_only_schema.test.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/type_timeline_only_schema.test.ts @@ -7,10 +7,10 @@ import { left } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; -import { exactCheck } from './exact_check'; -import { foldLeftRight, getPaths } from './__mocks__/utils'; import { TypeAndTimelineOnly, typeAndTimelineOnlySchema } from './type_timeline_only_schema'; import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags'; +import { exactCheck } from '../../../../../utils/build_validation/exact_check'; +import { foldLeftRight, getPaths } from '../../../../../utils/build_validation/__mocks__/utils'; describe('prepackaged_rule_schema', () => { beforeAll(() => { diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/iso_date_string.test.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/iso_date_string.test.ts index fbafaf7f52ecb6..ff62ea4443f3f6 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/iso_date_string.test.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/iso_date_string.test.ts @@ -6,8 +6,8 @@ import { IsoDateString } from './iso_date_string'; import { pipe } from 'fp-ts/lib/pipeable'; -import { foldLeftRight, getPaths } from '../response/__mocks__/utils'; import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../../../utils/build_validation/__mocks__/utils'; describe('ios_date_string', () => { test('it should validate a iso string', () => { diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/lists_default_array.test.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/lists_default_array.test.ts index e8a9c7b0886a19..2a97c8a4a143e8 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/lists_default_array.test.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/lists_default_array.test.ts @@ -6,8 +6,8 @@ import { ListsDefaultArray } from './lists_default_array'; import { pipe } from 'fp-ts/lib/pipeable'; -import { foldLeftRight, getPaths } from '../response/__mocks__/utils'; import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../../../utils/build_validation/__mocks__/utils'; describe('lists_default_array', () => { test('it should validate an empty array', () => { diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/positive_integer_greater_than_zero.test.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/positive_integer_greater_than_zero.test.ts index bc17303f242038..d6f21681df88fe 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/positive_integer_greater_than_zero.test.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/positive_integer_greater_than_zero.test.ts @@ -6,8 +6,8 @@ import { PositiveIntegerGreaterThanZero } from './positive_integer_greater_than_zero'; import { pipe } from 'fp-ts/lib/pipeable'; -import { foldLeftRight, getPaths } from '../response/__mocks__/utils'; import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../../../utils/build_validation/__mocks__/utils'; describe('positive_integer_greater_than_zero', () => { test('it should validate a positive number', () => { diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/postive_integer.test.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/postive_integer.test.ts index cee451279663a7..26441745a7f29e 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/postive_integer.test.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/postive_integer.test.ts @@ -6,8 +6,8 @@ import { PositiveInteger } from './positive_integer'; import { pipe } from 'fp-ts/lib/pipeable'; -import { foldLeftRight, getPaths } from '../response/__mocks__/utils'; import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../../../utils/build_validation/__mocks__/utils'; describe('positive_integer_greater_than_zero', () => { test('it should validate a positive number', () => { diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/references_default_array.test.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/references_default_array.test.ts index 3ae8415b4f170f..76f722274ce23a 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/references_default_array.test.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/references_default_array.test.ts @@ -6,8 +6,8 @@ import { ReferencesDefaultArray } from './references_default_array'; import { pipe } from 'fp-ts/lib/pipeable'; -import { foldLeftRight, getPaths } from '../response/__mocks__/utils'; import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../../../utils/build_validation/__mocks__/utils'; describe('references_default_array', () => { test('it should validate an empty array', () => { diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/risk_score.test.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/risk_score.test.ts index ab3f80944489fe..76e3445358dd9b 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/risk_score.test.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/risk_score.test.ts @@ -6,8 +6,8 @@ import { RiskScore } from './risk_score'; import { pipe } from 'fp-ts/lib/pipeable'; -import { foldLeftRight, getPaths } from '../response/__mocks__/utils'; import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../../../utils/build_validation/__mocks__/utils'; describe('risk_score', () => { test('it should validate a positive number', () => { diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/uuid.test.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/uuid.test.ts index 342e6f2db2e16d..7b68dbcef2d7ed 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/uuid.test.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/types/uuid.test.ts @@ -6,8 +6,8 @@ import { UUID } from './uuid'; import { pipe } from 'fp-ts/lib/pipeable'; -import { foldLeftRight, getPaths } from '../response/__mocks__/utils'; import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../../../utils/build_validation/__mocks__/utils'; describe('uuid', () => { test('it should validate a uuid', () => { diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/export_timelines_route.test.ts b/x-pack/plugins/siem/server/lib/timeline/routes/export_timelines_route.test.ts index 47ca25e16bd50d..2bccb7c393837b 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/export_timelines_route.test.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/export_timelines_route.test.ts @@ -85,7 +85,7 @@ describe('export timelines', () => { const result = server.validate(request); expect(result.badRequest.mock.calls[0][0]).toEqual( - 'Invalid value undefined supplied to : { ids: Array }/ids: Array' + 'Invalid value "undefined" supplied to "ids"' ); }); @@ -98,11 +98,7 @@ describe('export timelines', () => { const result = server.validate(request); expect(result.badRequest.mock.calls[1][0]).toEqual( - [ - 'Invalid value undefined supplied to : { file_name: string, exclude_export_details: ("true" | "false") }/file_name: string', - 'Invalid value undefined supplied to : { file_name: string, exclude_export_details: ("true" | "false") }/exclude_export_details: ("true" | "false")/0: "true"', - 'Invalid value undefined supplied to : { file_name: string, exclude_export_details: ("true" | "false") }/exclude_export_details: ("true" | "false")/1: "false"', - ].join('\n') + 'Invalid value "undefined" supplied to "file_name",Invalid value "undefined" supplied to "exclude_export_details",Invalid value "undefined" supplied to "exclude_export_details"' ); }); }); diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.test.ts b/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.test.ts index 3931bf0e5bea51..9f41943cfa27f7 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.test.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.test.ts @@ -332,10 +332,7 @@ describe('import timelines', () => { const result = server.validate(request); expect(result.badRequest).toHaveBeenCalledWith( - [ - 'Invalid value undefined supplied to : { file: (ReadableRt & { hapi: { filename: string } }) }/file: (ReadableRt & { hapi: { filename: string } })/0: ReadableRt', - 'Invalid value undefined supplied to : { file: (ReadableRt & { hapi: { filename: string } }) }/file: (ReadableRt & { hapi: { filename: string } })/1: { hapi: { filename: string } }', - ].join('\n') + 'Invalid value "undefined" supplied to "file",Invalid value "undefined" supplied to "file"' ); }); }); diff --git a/x-pack/plugins/siem/server/utils/build_validation/__mocks__/utils.ts b/x-pack/plugins/siem/server/utils/build_validation/__mocks__/utils.ts new file mode 100644 index 00000000000000..578972dda5aeff --- /dev/null +++ b/x-pack/plugins/siem/server/utils/build_validation/__mocks__/utils.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { fold } from 'fp-ts/lib/Either'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { formatErrors } from '../format_errors'; + +interface Message { + errors: t.Errors; + schema: T | {}; +} + +const onLeft = (errors: t.Errors): Message => { + return { schema: {}, errors }; +}; + +const onRight = (schema: T): Message => { + return { + schema, + errors: [], + }; +}; + +export const foldLeftRight = fold(onLeft, onRight); + +/** + * Convenience utility to keep the error message handling within tests to be + * very concise. + * @param validation The validation to get the errors from + */ +export const getPaths = (validation: t.Validation): string[] => { + return pipe( + validation, + fold( + errors => formatErrors(errors), + () => ['no errors'] + ) + ); +}; diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/exact_check.test.ts b/x-pack/plugins/siem/server/utils/build_validation/exact_check.test.ts similarity index 94% rename from x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/exact_check.test.ts rename to x-pack/plugins/siem/server/utils/build_validation/exact_check.test.ts index cae4365d06856f..1e70deaeed4386 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/exact_check.test.ts +++ b/x-pack/plugins/siem/server/utils/build_validation/exact_check.test.ts @@ -5,22 +5,13 @@ */ import * as t from 'io-ts'; -import { left, right } from 'fp-ts/lib/Either'; +import { left, right, Either } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; import { foldLeftRight, getPaths } from './__mocks__/utils'; import { exactCheck, findDifferencesRecursive } from './exact_check'; -import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags'; describe('exact_check', () => { - beforeAll(() => { - setFeatureFlagsForTestsOnly(); - }); - - afterAll(() => { - unSetFeatureFlagsForTestsOnly(); - }); - test('it returns an error if given extra object properties', () => { const someType = t.exact( t.type({ @@ -36,14 +27,22 @@ describe('exact_check', () => { }); test('it returns an error if the data type is not as expected', () => { + type UnsafeCastForTest = Either< + t.Errors, + { + a: number; + } + >; + const someType = t.exact( t.type({ a: t.string, }) ); + const payload = { a: 1 }; const decoded = someType.decode(payload); - const checked = exactCheck(payload, decoded); + const checked = exactCheck(payload, decoded as UnsafeCastForTest); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "1" supplied to "a"']); expect(message.schema).toEqual({}); diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/exact_check.ts b/x-pack/plugins/siem/server/utils/build_validation/exact_check.ts similarity index 59% rename from x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/exact_check.ts rename to x-pack/plugins/siem/server/utils/build_validation/exact_check.ts index 6fa04729501892..9484765f9973df 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/exact_check.ts +++ b/x-pack/plugins/siem/server/utils/build_validation/exact_check.ts @@ -25,10 +25,7 @@ import { isObject, get } from 'lodash/fp'; * @param decoded The decoded either which has either an existing error or the * decoded object which could have additional keys stripped from it. */ -export const exactCheck = ( - original: object, - decoded: Either -): Either => { +export const exactCheck = (original: T, decoded: Either): Either => { const onLeft = (errors: t.Errors): Either => left(errors); const onRight = (decodedValue: T): Either => { const differences = findDifferencesRecursive(original, decodedValue); @@ -47,7 +44,7 @@ export const exactCheck = ( return pipe(decoded, fold(onLeft, onRight)); }; -export const findDifferencesRecursive = (original: object, decodedValue: T): string[] => { +export const findDifferencesRecursive = (original: T, decodedValue: T): string[] => { if (decodedValue == null) { try { // It is null and painful when the original contains an object or an array @@ -56,29 +53,33 @@ export const findDifferencesRecursive = (original: object, decodedValue: T): } catch (err) { return ['circular reference']; } + } else if (typeof original !== 'object' || original == null) { + // We are not an object or null so do not report differences + return []; + } else { + const decodedKeys = Object.keys(decodedValue); + const differences = Object.keys(original).flatMap(originalKey => { + const foundKey = decodedKeys.some(key => key === originalKey); + const topLevelKey = foundKey ? [] : [originalKey]; + // I use lodash to cheat and get an any (not going to lie ;-)) + const valueObjectOrArrayOriginal = get(originalKey, original); + const valueObjectOrArrayDecoded = get(originalKey, decodedValue); + if (isObject(valueObjectOrArrayOriginal)) { + return [ + ...topLevelKey, + ...findDifferencesRecursive(valueObjectOrArrayOriginal, valueObjectOrArrayDecoded), + ]; + } else if (Array.isArray(valueObjectOrArrayOriginal)) { + return [ + ...topLevelKey, + ...valueObjectOrArrayOriginal.flatMap((arrayElement, index) => + findDifferencesRecursive(arrayElement, get(index, valueObjectOrArrayDecoded)) + ), + ]; + } else { + return topLevelKey; + } + }); + return differences; } - const decodedKeys = Object.keys(decodedValue); - const differences = Object.keys(original).flatMap(originalKey => { - const foundKey = decodedKeys.some(key => key === originalKey); - const topLevelKey = foundKey ? [] : [originalKey]; - // I use lodash to cheat and get an any (not going to lie ;-)) - const valueObjectOrArrayOriginal = get(originalKey, original); - const valueObjectOrArrayDecoded = get(originalKey, decodedValue); - if (isObject(valueObjectOrArrayOriginal)) { - return [ - ...topLevelKey, - ...findDifferencesRecursive(valueObjectOrArrayOriginal, valueObjectOrArrayDecoded), - ]; - } else if (Array.isArray(valueObjectOrArrayOriginal)) { - return [ - ...topLevelKey, - ...valueObjectOrArrayOriginal.flatMap((arrayElement, index) => - findDifferencesRecursive(arrayElement, get(index, valueObjectOrArrayDecoded)) - ), - ]; - } else { - return topLevelKey; - } - }); - return differences; }; diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/utils.test.ts b/x-pack/plugins/siem/server/utils/build_validation/format_errors.test.ts similarity index 94% rename from x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/utils.test.ts rename to x-pack/plugins/siem/server/utils/build_validation/format_errors.test.ts index c1eb32be4895c2..f9dd9e76a1d9c6 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/utils.test.ts +++ b/x-pack/plugins/siem/server/utils/build_validation/format_errors.test.ts @@ -5,18 +5,9 @@ */ import * as t from 'io-ts'; -import { formatErrors } from './utils'; -import { setFeatureFlagsForTestsOnly, unSetFeatureFlagsForTestsOnly } from '../../../feature_flags'; +import { formatErrors } from './format_errors'; describe('utils', () => { - beforeAll(() => { - setFeatureFlagsForTestsOnly(); - }); - - afterAll(() => { - unSetFeatureFlagsForTestsOnly(); - }); - test('returns an empty error message string if there are no errors', () => { const errors: t.Errors = []; const output = formatErrors(errors); diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/utils.ts b/x-pack/plugins/siem/server/utils/build_validation/format_errors.ts similarity index 100% rename from x-pack/plugins/siem/server/lib/detection_engine/routes/schemas/response/utils.ts rename to x-pack/plugins/siem/server/utils/build_validation/format_errors.ts diff --git a/x-pack/plugins/siem/server/utils/build_validation/route_validation.test.ts b/x-pack/plugins/siem/server/utils/build_validation/route_validation.test.ts index d17a8457ff81be..866dbe9480ca59 100644 --- a/x-pack/plugins/siem/server/utils/build_validation/route_validation.test.ts +++ b/x-pack/plugins/siem/server/utils/build_validation/route_validation.test.ts @@ -9,9 +9,33 @@ import * as rt from 'io-ts'; import { RouteValidationResultFactory } from '../../../../../../src/core/server/http'; describe('buildRouteValidation', () => { - const schema = rt.type({ - ids: rt.array(rt.string), - }); + const schema = rt.exact( + rt.type({ + ids: rt.array(rt.string), + }) + ); + type Schema = rt.TypeOf; + + /** + * If your schema is using exact all the way down then the validation will + * catch any additional keys that should not be present within the validation + * when the route_validation uses the exact check. + */ + const deepSchema = rt.exact( + rt.type({ + topLevel: rt.exact( + rt.type({ + secondLevel: rt.exact( + rt.type({ + thirdLevel: rt.string, + }) + ), + }) + ), + }) + ); + type DeepSchema = rt.TypeOf; + const validationResult: RouteValidationResultFactory = { ok: jest.fn().mockImplementation(validatedInput => validatedInput), badRequest: jest.fn().mockImplementation(e => e), @@ -22,18 +46,41 @@ describe('buildRouteValidation', () => { }); test('return validation error', () => { - const input = { id: 'someId' }; + const input: Omit & { id: string } = { id: 'someId' }; const result = buildRouteValidation(schema)(input, validationResult); - expect(result).toEqual( - 'Invalid value undefined supplied to : { ids: Array }/ids: Array' - ); + expect(result).toEqual('Invalid value "undefined" supplied to "ids"'); }); test('return validated input', () => { - const input = { ids: ['someId'] }; + const input: Schema = { ids: ['someId'] }; const result = buildRouteValidation(schema)(input, validationResult); expect(result).toEqual(input); }); + + test('returns validation error if given extra keys on input for an array', () => { + const input: Schema & { somethingExtra: string } = { + ids: ['someId'], + somethingExtra: 'hello', + }; + const result = buildRouteValidation(schema)(input, validationResult); + expect(result).toEqual('invalid keys "somethingExtra"'); + }); + + test('return validation input for a deep 3rd level object', () => { + const input: DeepSchema = { topLevel: { secondLevel: { thirdLevel: 'hello' } } }; + const result = buildRouteValidation(deepSchema)(input, validationResult); + expect(result).toEqual(input); + }); + + test('return validation error for a deep 3rd level object that has an extra key value of "somethingElse"', () => { + const input: DeepSchema & { + topLevel: { secondLevel: { thirdLevel: string; somethingElse: string } }; + } = { + topLevel: { secondLevel: { thirdLevel: 'hello', somethingElse: 'extraKey' } }, + }; + const result = buildRouteValidation(deepSchema)(input, validationResult); + expect(result).toEqual('invalid keys "somethingElse"'); + }); }); diff --git a/x-pack/plugins/siem/server/utils/build_validation/route_validation.ts b/x-pack/plugins/siem/server/utils/build_validation/route_validation.ts index bfcd0998fe6900..30b95dcfa94ee3 100644 --- a/x-pack/plugins/siem/server/utils/build_validation/route_validation.ts +++ b/x-pack/plugins/siem/server/utils/build_validation/route_validation.ts @@ -7,12 +7,13 @@ import { fold } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; import * as rt from 'io-ts'; -import { failure } from 'io-ts/lib/PathReporter'; import { RouteValidationFunction, RouteValidationResultFactory, RouteValidationError, } from '../../../../../../src/core/server'; +import { exactCheck } from './exact_check'; +import { formatErrors } from './format_errors'; type RequestValidationResult = | { @@ -32,8 +33,9 @@ export const buildRouteValidation = >( ) => pipe( schema.decode(inputValue), + decoded => exactCheck(inputValue, decoded), fold>( - (errors: rt.Errors) => validationResult.badRequest(failure(errors).join('\n')), + (errors: rt.Errors) => validationResult.badRequest(formatErrors(errors).join()), (validatedInput: A) => validationResult.ok(validatedInput) ) ); diff --git a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_stats_with_xpack.test.ts b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_stats_with_xpack.test.ts index f2a9995098e594..5dfe3d3e99a7f3 100644 --- a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_stats_with_xpack.test.ts +++ b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_stats_with_xpack.test.ts @@ -31,7 +31,6 @@ const kibana = { const getContext = () => ({ version: '8675309-snapshot', - isDev: true, logger: coreMock.createPluginInitializerContext().logger.get('test'), }); diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 1170d270e42acb..209a3f626272fa 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -2244,7 +2244,6 @@ "kbn.management.editIndexPattern.scripted.table.nameHeader": "名前", "kbn.management.editIndexPattern.scripted.table.scriptDescription": "フィールドのスクリプトです", "kbn.management.editIndexPattern.scripted.table.scriptHeader": "スクリプト", - "kbn.management.editIndexPattern.scripted.unknownModeErrorMessage": "不明なフィールド設定モード {mode}", "kbn.management.editIndexPattern.scriptedHeader": "スクリプトフィールド", "kbn.management.editIndexPattern.scriptedLabel": "ビジュアライゼーションにスクリプトフィールドを使用し、ドキュメントに表示させることができます。但し、スクリプトフィールドは検索できません。", "kbn.management.editIndexPattern.setDefaultAria": "デフォルトのインデックスに設定", @@ -9478,8 +9477,6 @@ "xpack.ml.dataframe.analytics.classificationExploration.evaluateJobIdTitle": "分類ジョブID {jobId}の評価", "xpack.ml.dataframe.analytics.classificationExploration.firstDocumentsShownHelpText": "予測がある最初の{searchSize}のドキュメントを示す", "xpack.ml.dataframe.analytics.classificationExploration.generalizationDocsCount": "{docsCount, plural, one {# doc} other {# docs}}が評価されました", - "xpack.ml.dataframe.analytics.classificationExploration.indexArrayBadgeContent": "配列", - "xpack.ml.dataframe.analytics.classificationExploration.indexArrayToolTipContent": "この配列ベースの列の完全なコンテンツは表示できません。", "xpack.ml.dataframe.analytics.classificationExploration.jobCapsFetchError": "結果を取得できません。インデックスのフィールドデータの読み込み中にエラーが発生しました。", "xpack.ml.dataframe.analytics.classificationExploration.jobConfigurationFetchError": "結果を取得できません。ジョブ構成データの読み込み中にエラーが発生しました。", "xpack.ml.dataframe.analytics.classificationExploration.jobConfigurationNoResultsMessage": "結果が見つかりませんでした。", @@ -9574,8 +9571,6 @@ "xpack.ml.dataframe.analytics.regressionExploration.generalizationDocsCount": "{docsCount, plural, one {# doc} other {# docs}}が評価されました", "xpack.ml.dataframe.analytics.regressionExploration.generalizationErrorTitle": "一般化エラー", "xpack.ml.dataframe.analytics.regressionExploration.indexError": "インデックスデータの読み込み中にエラーが発生しました。", - "xpack.ml.dataframe.analytics.regressionExploration.isTestingLabel": "テスト", - "xpack.ml.dataframe.analytics.regressionExploration.isTrainingLabel": "トレーニング", "xpack.ml.dataframe.analytics.regressionExploration.jobCapsFetchError": "結果を取得できません。インデックスのフィールドデータの読み込み中にエラーが発生しました。", "xpack.ml.dataframe.analytics.regressionExploration.jobConfigurationFetchError": "結果を取得できません。ジョブ構成データの読み込み中にエラーが発生しました。", "xpack.ml.dataframe.analytics.regressionExploration.meanSquaredErrorText": "平均二乗エラー", @@ -9587,9 +9582,6 @@ "xpack.ml.dataframe.analytics.regressionExploration.queryParsingErrorMessage": "クエリをパースできません。", "xpack.ml.dataframe.analytics.regressionExploration.rSquaredText": "R の二乗", "xpack.ml.dataframe.analytics.regressionExploration.rSquaredTooltipContent": "適合度を表します。モデルによる観察された結果の複製の効果を測定します。", - "xpack.ml.dataframe.analytics.regressionExploration.searchBoxPlaceholder": "例: 平均>0.5", - "xpack.ml.dataframe.analytics.regressionExploration.selectColumnsAriaLabel": "列を選択", - "xpack.ml.dataframe.analytics.regressionExploration.selectFieldsPopoverTitle": "フィールドを選択", "xpack.ml.dataframe.analytics.regressionExploration.tableJobIdTitle": "回帰ジョブID {jobId}のデスティネーションインデックス", "xpack.ml.dataframe.analytics.regressionExploration.trainingDocsCount": "{docsCount, plural, one {# doc} other {# docs}}が評価されました", "xpack.ml.dataframe.analytics.regressionExploration.trainingErrorTitle": "トレーニングエラー", @@ -16254,7 +16246,6 @@ "xpack.uptime.locationName.helpLinkAnnotation": "場所を追加", "xpack.uptime.ml.durationChart.exploreInMlApp": "ML アプリで探索", "xpack.uptime.ml.enableAnomalyDetectionPanel.anomalyDetectionTitle": "異常検知", - "xpack.uptime.ml.enableAnomalyDetectionPanel.callout.jobExistsDescription.viewJobLinkText": "既存のジョブを表示", "xpack.uptime.ml.enableAnomalyDetectionPanel.createMLJobDescription": "ここでは稼働状況監視の応答時間について異常スコアを計算する機械学習ジョブを作成できます。\n 有効にすると、詳細ページの監視期間チャートに予想範囲が表示され、グラフに異常の注釈が付きます。\n 地理的な地域にわたって遅延が増える期間を特定することもできます。", "xpack.uptime.ml.enableAnomalyDetectionPanel.createNewJobButtonLabel": "新規ジョブを作成", "xpack.uptime.ml.enableAnomalyDetectionPanel.disableAnomalyDetectionTitle": "異常検知を無効にする", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index f86e03b6c10e15..5d8d733f2b5b68 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -2245,7 +2245,6 @@ "kbn.management.editIndexPattern.scripted.table.nameHeader": "名称", "kbn.management.editIndexPattern.scripted.table.scriptDescription": "字段的脚本", "kbn.management.editIndexPattern.scripted.table.scriptHeader": "脚本", - "kbn.management.editIndexPattern.scripted.unknownModeErrorMessage": "未知 fieldSettings 模式 {mode}", "kbn.management.editIndexPattern.scriptedHeader": "脚本字段", "kbn.management.editIndexPattern.scriptedLabel": "可以在可视化中使用脚本字段,并在您的文档中显示它们。但是,您不能搜索脚本字段。", "kbn.management.editIndexPattern.setDefaultAria": "设置为默认索引", @@ -9481,8 +9480,6 @@ "xpack.ml.dataframe.analytics.classificationExploration.evaluateJobIdTitle": "分类作业 ID {jobId} 的评估", "xpack.ml.dataframe.analytics.classificationExploration.firstDocumentsShownHelpText": "正在显示有相关预测存在的前 {searchSize} 个文档", "xpack.ml.dataframe.analytics.classificationExploration.generalizationDocsCount": "{docsCount, plural, one {# 个文档} other {# 个文档}}已评估", - "xpack.ml.dataframe.analytics.classificationExploration.indexArrayBadgeContent": "数组", - "xpack.ml.dataframe.analytics.classificationExploration.indexArrayToolTipContent": "此基于数组的列的完整内容无法显示。", "xpack.ml.dataframe.analytics.classificationExploration.jobCapsFetchError": "无法提取结果。加载索引的字段数据时发生错误。", "xpack.ml.dataframe.analytics.classificationExploration.jobConfigurationFetchError": "无法提取结果。加载作业配置数据时发生错误。", "xpack.ml.dataframe.analytics.classificationExploration.jobConfigurationNoResultsMessage": "未找到结果。", @@ -9577,8 +9574,6 @@ "xpack.ml.dataframe.analytics.regressionExploration.generalizationDocsCount": "{docsCount, plural, one {# 个文档} other {# 个文档}}已评估", "xpack.ml.dataframe.analytics.regressionExploration.generalizationErrorTitle": "泛化误差", "xpack.ml.dataframe.analytics.regressionExploration.indexError": "加载索引数据时出错。", - "xpack.ml.dataframe.analytics.regressionExploration.isTestingLabel": "测试", - "xpack.ml.dataframe.analytics.regressionExploration.isTrainingLabel": "培训", "xpack.ml.dataframe.analytics.regressionExploration.jobCapsFetchError": "无法提取结果。加载索引的字段数据时发生错误。", "xpack.ml.dataframe.analytics.regressionExploration.jobConfigurationFetchError": "无法提取结果。加载作业配置数据时发生错误。", "xpack.ml.dataframe.analytics.regressionExploration.meanSquaredErrorText": "均方误差", @@ -9590,9 +9585,6 @@ "xpack.ml.dataframe.analytics.regressionExploration.queryParsingErrorMessage": "无法解析查询。", "xpack.ml.dataframe.analytics.regressionExploration.rSquaredText": "R 平方", "xpack.ml.dataframe.analytics.regressionExploration.rSquaredTooltipContent": "表示拟合优度。度量模型复制被观察结果的优良性。", - "xpack.ml.dataframe.analytics.regressionExploration.searchBoxPlaceholder": "例如 avg>0.5", - "xpack.ml.dataframe.analytics.regressionExploration.selectColumnsAriaLabel": "选择列", - "xpack.ml.dataframe.analytics.regressionExploration.selectFieldsPopoverTitle": "选择字段", "xpack.ml.dataframe.analytics.regressionExploration.tableJobIdTitle": "回归作业 ID {jobId} 的目标索引", "xpack.ml.dataframe.analytics.regressionExploration.trainingDocsCount": "{docsCount, plural, one {# 个文档} other {# 个文档}}已评估", "xpack.ml.dataframe.analytics.regressionExploration.trainingErrorTitle": "训练误差", @@ -16259,7 +16251,6 @@ "xpack.uptime.locationName.helpLinkAnnotation": "添加位置", "xpack.uptime.ml.durationChart.exploreInMlApp": "在 ML 应用中浏览", "xpack.uptime.ml.enableAnomalyDetectionPanel.anomalyDetectionTitle": "异常检测", - "xpack.uptime.ml.enableAnomalyDetectionPanel.callout.jobExistsDescription.viewJobLinkText": "查看现有作业", "xpack.uptime.ml.enableAnomalyDetectionPanel.createMLJobDescription": "在此处可以创建 Machine Learning 作业,以便为运行时间监测计算\n 响应持续时间的异常分数。启用后,详情页面上的监测持续时间图表\n 将显示预期边界并使用异常标注图表。您还可能\n 识别在所有地理区域的延迟增长时段。", "xpack.uptime.ml.enableAnomalyDetectionPanel.createNewJobButtonLabel": "创建新作业", "xpack.uptime.ml.enableAnomalyDetectionPanel.disableAnomalyDetectionTitle": "禁用异常检测", diff --git a/x-pack/test/api_integration/apis/management/ingest_pipelines/ingest_pipelines.ts b/x-pack/test/api_integration/apis/management/ingest_pipelines/ingest_pipelines.ts index 41f285938c003d..a1773a052ede26 100644 --- a/x-pack/test/api_integration/apis/management/ingest_pipelines/ingest_pipelines.ts +++ b/x-pack/test/api_integration/apis/management/ingest_pipelines/ingest_pipelines.ts @@ -185,5 +185,104 @@ export default function({ getService }: FtrProviderContext) { }); }); }); + + describe('Delete', () => { + const PIPELINE = { + description: 'test pipeline description', + processors: [ + { + script: { + source: 'ctx._type = null', + }, + }, + ], + version: 1, + }; + + it('should delete a pipeline', async () => { + // Create pipeline to be deleted + const PIPELINE_ID = 'test_delete_pipeline'; + createPipeline({ body: PIPELINE, id: PIPELINE_ID }); + + const uri = `${API_BASE_PATH}/${PIPELINE_ID}`; + + const { body } = await supertest + .delete(uri) + .set('kbn-xsrf', 'xxx') + .expect(200); + + expect(body).to.eql({ + itemsDeleted: [PIPELINE_ID], + errors: [], + }); + }); + + it('should delete multiple pipelines', async () => { + // Create pipelines to be deleted + const PIPELINE_ONE_ID = 'test_delete_pipeline_1'; + const PIPELINE_TWO_ID = 'test_delete_pipeline_2'; + createPipeline({ body: PIPELINE, id: PIPELINE_ONE_ID }); + createPipeline({ body: PIPELINE, id: PIPELINE_TWO_ID }); + + const uri = `${API_BASE_PATH}/${PIPELINE_ONE_ID},${PIPELINE_TWO_ID}`; + + const { + body: { itemsDeleted, errors }, + } = await supertest + .delete(uri) + .set('kbn-xsrf', 'xxx') + .expect(200); + + expect(errors).to.eql([]); + + // The itemsDeleted array order isn't guaranteed, so we assert against each pipeline name instead + [PIPELINE_ONE_ID, PIPELINE_TWO_ID].forEach(pipelineName => { + expect(itemsDeleted.includes(pipelineName)).to.be(true); + }); + }); + + it('should return an error for any pipelines not sucessfully deleted', async () => { + const PIPELINE_DOES_NOT_EXIST = 'pipeline_does_not_exist'; + + // Create pipeline to be deleted + const PIPELINE_ONE_ID = 'test_delete_pipeline_1'; + createPipeline({ body: PIPELINE, id: PIPELINE_ONE_ID }); + + const uri = `${API_BASE_PATH}/${PIPELINE_ONE_ID},${PIPELINE_DOES_NOT_EXIST}`; + + const { body } = await supertest + .delete(uri) + .set('kbn-xsrf', 'xxx') + .expect(200); + + expect(body).to.eql({ + itemsDeleted: [PIPELINE_ONE_ID], + errors: [ + { + name: PIPELINE_DOES_NOT_EXIST, + error: { + msg: '[resource_not_found_exception] pipeline [pipeline_does_not_exist] is missing', + path: '/_ingest/pipeline/pipeline_does_not_exist', + query: {}, + statusCode: 404, + response: JSON.stringify({ + error: { + root_cause: [ + { + type: 'resource_not_found_exception', + reason: 'pipeline [pipeline_does_not_exist] is missing', + }, + ], + type: 'resource_not_found_exception', + reason: 'pipeline [pipeline_does_not_exist] is missing', + }, + status: 404, + }), + }, + }, + ], + }); + }); + }); }); } diff --git a/x-pack/test/reporting/functional/reporting.js b/x-pack/test/reporting/functional/reporting.js index 6107363986a409..c1a2ae634662ca 100644 --- a/x-pack/test/reporting/functional/reporting.js +++ b/x-pack/test/reporting/functional/reporting.js @@ -24,6 +24,7 @@ export default function({ getService, getPageObjects }) { const browser = getService('browser'); const log = getService('log'); const config = getService('config'); + const filterBar = getService('filterBar'); const PageObjects = getPageObjects([ 'reporting', 'common', @@ -161,7 +162,27 @@ export default function({ getService, getPageObjects }) { expect(await PageObjects.reporting.isGenerateReportButtonDisabled()).to.be(null); }); + it('becomes available/not available when a saved search is created, changed and saved again', async () => { + // create new search, csv export is not available + await PageObjects.discover.clickNewSearchButton(); + await PageObjects.reporting.openCsvReportingPanel(); + expect(await PageObjects.reporting.isGenerateReportButtonDisabled()).to.be('true'); + // save search, csv export is available + await PageObjects.discover.saveSearch('my search - expectEnabledGenerateReportButton 2'); + await PageObjects.reporting.openCsvReportingPanel(); + expect(await PageObjects.reporting.isGenerateReportButtonDisabled()).to.be(null); + // add filter, csv export is not available + await filterBar.addFilter('currency', 'is', 'EUR'); + await PageObjects.reporting.openCsvReportingPanel(); + expect(await PageObjects.reporting.isGenerateReportButtonDisabled()).to.be('true'); + // save search again, csv export is available + await PageObjects.discover.saveSearch('my search - expectEnabledGenerateReportButton 2'); + await PageObjects.reporting.openCsvReportingPanel(); + expect(await PageObjects.reporting.isGenerateReportButtonDisabled()).to.be(null); + }); + it('generates a report with data', async () => { + await PageObjects.discover.clickNewSearchButton(); await PageObjects.reporting.setTimepickerInDataRange(); await PageObjects.discover.saveSearch('my search - with data - expectReportCanBeCreated'); await PageObjects.reporting.openCsvReportingPanel(); diff --git a/yarn.lock b/yarn.lock index 45540cd2675b74..b47befbf9057b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4477,10 +4477,10 @@ dependencies: "@types/node" "*" -"@types/papaparse@^4.5.11": - version "4.5.11" - resolved "https://registry.yarnpkg.com/@types/papaparse/-/papaparse-4.5.11.tgz#dcd4f64da55f768c2e2cf92ccac1973c67a73890" - integrity sha512-zOw6K7YyA/NuZ2yZ8lzZFe2U3fn+vFfcRfiQp4ZJHG6y8WYWy2SYFbq6mp4yUgpIruJHBjKZtgyE0vvCoWEq+A== +"@types/papaparse@^5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/papaparse/-/papaparse-5.0.3.tgz#7cedc1ebc9484819af8306a8b42f9f08ca9bdb44" + integrity sha512-SgWGWnBGxl6XgjKDM2eoDg163ZFQtH6m6C2aOuaAf1T2gUB3rjaiPDDARbY9WlacRgZqieRG9imAfJaJ+5ouDA== dependencies: "@types/node" "*" @@ -22585,10 +22585,10 @@ pako@~1.0.5: resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" integrity sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg== -papaparse@^4.6.3: - version "4.6.3" - resolved "https://registry.yarnpkg.com/papaparse/-/papaparse-4.6.3.tgz#742e5eaaa97fa6c7e1358d2934d8f18f44aee781" - integrity sha512-LRq7BrHC2kHPBYSD50aKuw/B/dGcg29omyJbKWY3KsYUZU69RKwaBHu13jGmCYBtOc4odsLCrFyk6imfyNubJQ== +papaparse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/papaparse/-/papaparse-5.2.0.tgz#97976a1b135c46612773029153dc64995caa3b7b" + integrity sha512-ylq1wgUSnagU+MKQtNeVqrPhZuMYBvOSL00DHycFTCxownF95gpLAk1HiHdUW77N8yxRq1qHXLdlIPyBSG9NSA== parallel-transform@^1.1.0: version "1.1.0"