diff --git a/.buildkite/scripts/common/env.sh b/.buildkite/scripts/common/env.sh index cd33cdc714cbe..0715b07fd58e8 100755 --- a/.buildkite/scripts/common/env.sh +++ b/.buildkite/scripts/common/env.sh @@ -42,7 +42,11 @@ if is_pr; then export ELASTIC_APM_ACTIVE=false fi - export CHECKS_REPORTER_ACTIVE=true + if [[ "${GITHUB_STEP_COMMIT_STATUS_ENABLED:-}" != "true" ]]; then + export CHECKS_REPORTER_ACTIVE=true + else + export CHECKS_REPORTER_ACTIVE=false + fi # These can be removed once we're not supporting Jenkins and Buildkite at the same time # These are primarily used by github checks reporter and can be configured via /github_checks_api.json diff --git a/.buildkite/scripts/lifecycle/post_build.sh b/.buildkite/scripts/lifecycle/post_build.sh index 35e5a6006ee24..5a181e8fa5489 100755 --- a/.buildkite/scripts/lifecycle/post_build.sh +++ b/.buildkite/scripts/lifecycle/post_build.sh @@ -5,7 +5,9 @@ set -euo pipefail BUILD_SUCCESSFUL=$(node "$(dirname "${0}")/build_status.js") export BUILD_SUCCESSFUL -"$(dirname "${0}")/commit_status_complete.sh" +if [[ "${GITHUB_BUILD_COMMIT_STATUS_ENABLED:-}" != "true" ]]; then + "$(dirname "${0}")/commit_status_complete.sh" +fi node "$(dirname "${0}")/ci_stats_complete.js" diff --git a/.buildkite/scripts/lifecycle/pre_build.sh b/.buildkite/scripts/lifecycle/pre_build.sh index d91597a00a080..d901594e36ce4 100755 --- a/.buildkite/scripts/lifecycle/pre_build.sh +++ b/.buildkite/scripts/lifecycle/pre_build.sh @@ -4,7 +4,9 @@ set -euo pipefail source .buildkite/scripts/common/util.sh -"$(dirname "${0}")/commit_status_start.sh" +if [[ "${GITHUB_BUILD_COMMIT_STATUS_ENABLED:-}" != "true" ]]; then + "$(dirname "${0}")/commit_status_start.sh" +fi export CI_STATS_TOKEN="$(retry 5 5 vault read -field=api_token secret/kibana-issues/dev/kibana_ci_stats)" export CI_STATS_HOST="$(retry 5 5 vault read -field=api_host secret/kibana-issues/dev/kibana_ci_stats)" diff --git a/config/kibana.yml b/config/kibana.yml index eeb7c84df4318..f6f85f057172c 100644 --- a/config/kibana.yml +++ b/config/kibana.yml @@ -1,3 +1,7 @@ +# For more configuration options see the configuration guide for Kibana in +# https://www.elastic.co/guide/index.html + +# =================== System: Kibana Server =================== # Kibana is served by a back end server. This setting specifies the port to use. #server.port: 5601 @@ -14,8 +18,7 @@ # Specifies whether Kibana should rewrite requests that are prefixed with # `server.basePath` or require that they are rewritten by your reverse proxy. -# This setting was effectively always `false` before Kibana 6.3 and will -# default to `true` starting in Kibana 7.0. +# Defaults to `false`. #server.rewriteBasePath: false # Specifies the public URL at which Kibana is available for end users. If @@ -25,9 +28,17 @@ # The maximum payload size in bytes for incoming server requests. #server.maxPayload: 1048576 -# The Kibana server's name. This is used for display purposes. +# The Kibana server's name. This is used for display purposes. #server.name: "your-hostname" +# =================== System: Kibana Server (Optional) =================== +# Enables SSL and paths to the PEM-format SSL certificate and SSL key files, respectively. +# These settings enable SSL for outgoing requests from the Kibana server to the browser. +#server.ssl.enabled: false +#server.ssl.certificate: /path/to/your/server.crt +#server.ssl.key: /path/to/your/server.key + +# =================== System: Elasticsearch =================== # The URLs of the Elasticsearch instances to use for all your queries. #elasticsearch.hosts: ["http://localhost:9200"] @@ -39,28 +50,10 @@ #elasticsearch.password: "pass" # Kibana can also authenticate to Elasticsearch via "service account tokens". -# If may use this token instead of a username/password. +# Service account tokens are Bearer style tokens that replace the traditional username/password based configuration. +# Use this token instead of a username/password. # elasticsearch.serviceAccountToken: "my_token" -# Enables SSL and paths to the PEM-format SSL certificate and SSL key files, respectively. -# These settings enable SSL for outgoing requests from the Kibana server to the browser. -#server.ssl.enabled: false -#server.ssl.certificate: /path/to/your/server.crt -#server.ssl.key: /path/to/your/server.key - -# Optional settings that provide the paths to the PEM-format SSL certificate and key files. -# These files are used to verify the identity of Kibana to Elasticsearch and are required when -# xpack.security.http.ssl.client_authentication in Elasticsearch is set to required. -#elasticsearch.ssl.certificate: /path/to/your/client.crt -#elasticsearch.ssl.key: /path/to/your/client.key - -# Optional setting that enables you to specify a path to the PEM file for the certificate -# authority for your Elasticsearch instance. -#elasticsearch.ssl.certificateAuthorities: [ "/path/to/your/CA.pem" ] - -# To disregard the validity of SSL certificates, change this setting's value to 'none'. -#elasticsearch.ssl.verificationMode: full - # Time in milliseconds to wait for Elasticsearch to respond to pings. Defaults to the value of # the elasticsearch.requestTimeout setting. #elasticsearch.pingTimeout: 1500 @@ -80,10 +73,21 @@ # Time in milliseconds for Elasticsearch to wait for responses from shards. Set to 0 to disable. #elasticsearch.shardTimeout: 30000 -# Specifies the path where Kibana creates the process ID file. -#pid.file: /run/kibana/kibana.pid +# =================== System: Elasticsearch (Optional) =================== +# These files are used to verify the identity of Kibana to Elasticsearch and are required when +# xpack.security.http.ssl.client_authentication in Elasticsearch is set to required. +#elasticsearch.ssl.certificate: /path/to/your/client.crt +#elasticsearch.ssl.key: /path/to/your/client.key + +# Enables you to specify a path to the PEM file for the certificate +# authority for your Elasticsearch instance. +#elasticsearch.ssl.certificateAuthorities: [ "/path/to/your/CA.pem" ] + +# To disregard the validity of SSL certificates, change this setting's value to 'none'. +#elasticsearch.ssl.verificationMode: full -# Set the value of this setting to off to suppress all logging output, or to debug to log everything. +# =================== System: Logging =================== +# Set the value of this setting to off to suppress all logging output, or to debug to log everything. Defaults to 'info' #logging.root.level: debug # Enables you to specify a file where Kibana stores log output. @@ -108,10 +112,47 @@ # - name: metrics.ops # level: debug +# =================== System: Other =================== +# The path where Kibana stores persistent data not saved in Elasticsearch. Defaults to data +#path.data: data + +# Specifies the path where Kibana creates the process ID file. +#pid.file: /run/kibana/kibana.pid + # Set the interval in milliseconds to sample system and process performance -# metrics. Minimum is 100ms. Defaults to 5000. +# metrics. Minimum is 100ms. Defaults to 5000ms. #ops.interval: 5000 # Specifies locale to be used for all localizable strings, dates and number formats. # Supported languages are the following: English - en , by default , Chinese - zh-CN . #i18n.locale: "en" + +# =================== Frequently used (Optional)=================== + +# =================== Saved Objects: Migrations =================== +# Saved object migrations run at startup. If you run into migration-related issues, you might need to adjust these settings. + +# The number of documents migrated at a time. +# If Kibana can't start up or upgrade due to an Elasticsearch `circuit_breaking_exception`, +# use a smaller batchSize value to reduce the memory pressure. Defaults to 1000 objects per batch. +#migrations.batchSize: 1000 + +# The maximum payload size for indexing batches of upgraded saved objects. +# To avoid migrations failing due to a 413 Request Entity Too Large response from Elasticsearch. +# This value should be lower than or equal to your Elasticsearch cluster’s `http.max_content_length` +# configuration option. Default: 100mb +#migrations.maxBatchSizeBytes: 100mb + +# The number of times to retry temporary migration failures. Increase the setting +# if migrations fail frequently with a message such as `Unable to complete the [...] step after +# 15 attempts, terminating`. Defaults to 15 +#migrations.retryAttempts: 15 + +# =================== Search Autocomplete =================== +# Time in milliseconds to wait for autocomplete suggestions from Elasticsearch. +# This value must be a whole number greater than zero. Defaults to 1000ms +#data.autocomplete.valueSuggestions.timeout: 1000 + +# Maximum number of documents loaded by each shard to generate autocomplete suggestions. +# This value must be a whole number greater than zero. Defaults to 100_000 +#data.autocomplete.valueSuggestions.terminateAfter: 100000 diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md index 4e44df9d4e183..676f7420c8bb9 100644 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md +++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md @@ -261,5 +261,8 @@ readonly links: { readonly rubyOverview: string; readonly rustGuide: string; }; + readonly endpoints: { + readonly troubleshooting: string; + }; }; ``` diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md index 5871a84c5402e..788f0b9de8218 100644 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md +++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md @@ -17,5 +17,5 @@ export interface DocLinksStart | --- | --- | --- | | [DOC\_LINK\_VERSION](./kibana-plugin-core-public.doclinksstart.doc_link_version.md) | string | | | [ELASTIC\_WEBSITE\_URL](./kibana-plugin-core-public.doclinksstart.elastic_website_url.md) | string | | -| [links](./kibana-plugin-core-public.doclinksstart.links.md) | {
readonly settings: string;
readonly elasticStackGetStarted: string;
readonly apm: {
readonly kibanaSettings: string;
readonly supportedServiceMaps: string;
readonly customLinks: string;
readonly droppedTransactionSpans: string;
readonly upgrading: string;
readonly metaData: string;
};
readonly canvas: {
readonly guide: string;
};
readonly dashboard: {
readonly guide: string;
readonly drilldowns: string;
readonly drilldownsTriggerPicker: string;
readonly urlDrilldownTemplateSyntax: string;
readonly urlDrilldownVariables: string;
};
readonly discover: Record<string, string>;
readonly filebeat: {
readonly base: string;
readonly installation: string;
readonly configuration: string;
readonly elasticsearchOutput: string;
readonly elasticsearchModule: string;
readonly startup: string;
readonly exportedFields: string;
readonly suricataModule: string;
readonly zeekModule: string;
};
readonly auditbeat: {
readonly base: string;
readonly auditdModule: string;
readonly systemModule: string;
};
readonly metricbeat: {
readonly base: string;
readonly configure: string;
readonly httpEndpoint: string;
readonly install: string;
readonly start: string;
};
readonly enterpriseSearch: {
readonly base: string;
readonly appSearchBase: string;
readonly workplaceSearchBase: string;
};
readonly heartbeat: {
readonly base: string;
};
readonly libbeat: {
readonly getStarted: string;
};
readonly logstash: {
readonly base: string;
};
readonly functionbeat: {
readonly base: string;
};
readonly winlogbeat: {
readonly base: string;
};
readonly aggs: {
readonly composite: string;
readonly composite_missing_bucket: string;
readonly date_histogram: string;
readonly date_range: string;
readonly date_format_pattern: string;
readonly filter: string;
readonly filters: string;
readonly geohash_grid: string;
readonly histogram: string;
readonly ip_range: string;
readonly range: string;
readonly significant_terms: string;
readonly terms: string;
readonly avg: string;
readonly avg_bucket: string;
readonly max_bucket: string;
readonly min_bucket: string;
readonly sum_bucket: string;
readonly cardinality: string;
readonly count: string;
readonly cumulative_sum: string;
readonly derivative: string;
readonly geo_bounds: string;
readonly geo_centroid: string;
readonly max: string;
readonly median: string;
readonly min: string;
readonly moving_avg: string;
readonly percentile_ranks: string;
readonly serial_diff: string;
readonly std_dev: string;
readonly sum: string;
readonly top_hits: string;
};
readonly runtimeFields: {
readonly overview: string;
readonly mapping: string;
};
readonly scriptedFields: {
readonly scriptFields: string;
readonly scriptAggs: string;
readonly painless: string;
readonly painlessApi: string;
readonly painlessLangSpec: string;
readonly painlessSyntax: string;
readonly painlessWalkthrough: string;
readonly luceneExpressions: string;
};
readonly search: {
readonly sessions: string;
readonly sessionLimits: string;
};
readonly indexPatterns: {
readonly introduction: string;
readonly fieldFormattersNumber: string;
readonly fieldFormattersString: string;
readonly runtimeFields: string;
};
readonly addData: string;
readonly kibana: string;
readonly upgradeAssistant: string;
readonly rollupJobs: string;
readonly elasticsearch: Record<string, string>;
readonly siem: {
readonly privileges: string;
readonly guide: string;
readonly gettingStarted: string;
readonly ml: string;
readonly ruleChangeLog: string;
readonly detectionsReq: string;
readonly networkMap: string;
readonly troubleshootGaps: string;
};
readonly securitySolution: {
readonly trustedApps: string;
};
readonly query: {
readonly eql: string;
readonly kueryQuerySyntax: string;
readonly luceneQuerySyntax: string;
readonly percolate: string;
readonly queryDsl: string;
readonly autocompleteChanges: string;
};
readonly date: {
readonly dateMath: string;
readonly dateMathIndexNames: string;
};
readonly management: Record<string, string>;
readonly ml: Record<string, string>;
readonly transforms: Record<string, string>;
readonly visualize: Record<string, string>;
readonly apis: Readonly<{
bulkIndexAlias: string;
byteSizeUnits: string;
createAutoFollowPattern: string;
createFollower: string;
createIndex: string;
createSnapshotLifecyclePolicy: string;
createRoleMapping: string;
createRoleMappingTemplates: string;
createRollupJobsRequest: string;
createApiKey: string;
createPipeline: string;
createTransformRequest: string;
cronExpressions: string;
executeWatchActionModes: string;
indexExists: string;
openIndex: string;
putComponentTemplate: string;
painlessExecute: string;
painlessExecuteAPIContexts: string;
putComponentTemplateMetadata: string;
putSnapshotLifecyclePolicy: string;
putIndexTemplateV1: string;
putWatch: string;
simulatePipeline: string;
timeUnits: string;
updateTransform: string;
}>;
readonly observability: Readonly<{
guide: string;
infrastructureThreshold: string;
logsThreshold: string;
metricsThreshold: string;
monitorStatus: string;
monitorUptime: string;
tlsCertificate: string;
uptimeDurationAnomaly: string;
}>;
readonly alerting: Record<string, string>;
readonly maps: Record<string, string>;
readonly monitoring: Record<string, string>;
readonly security: Readonly<{
apiKeyServiceSettings: string;
clusterPrivileges: string;
elasticsearchSettings: string;
elasticsearchEnableSecurity: string;
elasticsearchEnableApiKeys: string;
indicesPrivileges: string;
kibanaTLS: string;
kibanaPrivileges: string;
mappingRoles: string;
mappingRolesFieldRules: string;
runAsPrivilege: string;
}>;
readonly spaces: Readonly<{
kibanaLegacyUrlAliases: string;
kibanaDisableLegacyUrlAliasesApi: string;
}>;
readonly watcher: Record<string, string>;
readonly ccs: Record<string, string>;
readonly plugins: Record<string, string>;
readonly snapshotRestore: Record<string, string>;
readonly ingest: Record<string, string>;
readonly fleet: Readonly<{
datastreamsILM: string;
beatsAgentComparison: string;
guide: string;
fleetServer: string;
fleetServerAddFleetServer: string;
settings: string;
settingsFleetServerHostSettings: string;
troubleshooting: string;
elasticAgent: string;
datastreams: string;
datastreamsNamingScheme: string;
installElasticAgent: string;
upgradeElasticAgent: string;
upgradeElasticAgent712lower: string;
learnMoreBlog: string;
apiKeysLearnMore: string;
}>;
readonly ecs: {
readonly guide: string;
};
readonly clients: {
readonly guide: string;
readonly goOverview: string;
readonly javaIndex: string;
readonly jsIntro: string;
readonly netGuide: string;
readonly perlGuide: string;
readonly phpGuide: string;
readonly pythonGuide: string;
readonly rubyOverview: string;
readonly rustGuide: string;
};
} | | +| [links](./kibana-plugin-core-public.doclinksstart.links.md) | {
readonly settings: string;
readonly elasticStackGetStarted: string;
readonly apm: {
readonly kibanaSettings: string;
readonly supportedServiceMaps: string;
readonly customLinks: string;
readonly droppedTransactionSpans: string;
readonly upgrading: string;
readonly metaData: string;
};
readonly canvas: {
readonly guide: string;
};
readonly dashboard: {
readonly guide: string;
readonly drilldowns: string;
readonly drilldownsTriggerPicker: string;
readonly urlDrilldownTemplateSyntax: string;
readonly urlDrilldownVariables: string;
};
readonly discover: Record<string, string>;
readonly filebeat: {
readonly base: string;
readonly installation: string;
readonly configuration: string;
readonly elasticsearchOutput: string;
readonly elasticsearchModule: string;
readonly startup: string;
readonly exportedFields: string;
readonly suricataModule: string;
readonly zeekModule: string;
};
readonly auditbeat: {
readonly base: string;
readonly auditdModule: string;
readonly systemModule: string;
};
readonly metricbeat: {
readonly base: string;
readonly configure: string;
readonly httpEndpoint: string;
readonly install: string;
readonly start: string;
};
readonly enterpriseSearch: {
readonly base: string;
readonly appSearchBase: string;
readonly workplaceSearchBase: string;
};
readonly heartbeat: {
readonly base: string;
};
readonly libbeat: {
readonly getStarted: string;
};
readonly logstash: {
readonly base: string;
};
readonly functionbeat: {
readonly base: string;
};
readonly winlogbeat: {
readonly base: string;
};
readonly aggs: {
readonly composite: string;
readonly composite_missing_bucket: string;
readonly date_histogram: string;
readonly date_range: string;
readonly date_format_pattern: string;
readonly filter: string;
readonly filters: string;
readonly geohash_grid: string;
readonly histogram: string;
readonly ip_range: string;
readonly range: string;
readonly significant_terms: string;
readonly terms: string;
readonly avg: string;
readonly avg_bucket: string;
readonly max_bucket: string;
readonly min_bucket: string;
readonly sum_bucket: string;
readonly cardinality: string;
readonly count: string;
readonly cumulative_sum: string;
readonly derivative: string;
readonly geo_bounds: string;
readonly geo_centroid: string;
readonly max: string;
readonly median: string;
readonly min: string;
readonly moving_avg: string;
readonly percentile_ranks: string;
readonly serial_diff: string;
readonly std_dev: string;
readonly sum: string;
readonly top_hits: string;
};
readonly runtimeFields: {
readonly overview: string;
readonly mapping: string;
};
readonly scriptedFields: {
readonly scriptFields: string;
readonly scriptAggs: string;
readonly painless: string;
readonly painlessApi: string;
readonly painlessLangSpec: string;
readonly painlessSyntax: string;
readonly painlessWalkthrough: string;
readonly luceneExpressions: string;
};
readonly search: {
readonly sessions: string;
readonly sessionLimits: string;
};
readonly indexPatterns: {
readonly introduction: string;
readonly fieldFormattersNumber: string;
readonly fieldFormattersString: string;
readonly runtimeFields: string;
};
readonly addData: string;
readonly kibana: string;
readonly upgradeAssistant: string;
readonly rollupJobs: string;
readonly elasticsearch: Record<string, string>;
readonly siem: {
readonly privileges: string;
readonly guide: string;
readonly gettingStarted: string;
readonly ml: string;
readonly ruleChangeLog: string;
readonly detectionsReq: string;
readonly networkMap: string;
readonly troubleshootGaps: string;
};
readonly securitySolution: {
readonly trustedApps: string;
};
readonly query: {
readonly eql: string;
readonly kueryQuerySyntax: string;
readonly luceneQuerySyntax: string;
readonly percolate: string;
readonly queryDsl: string;
readonly autocompleteChanges: string;
};
readonly date: {
readonly dateMath: string;
readonly dateMathIndexNames: string;
};
readonly management: Record<string, string>;
readonly ml: Record<string, string>;
readonly transforms: Record<string, string>;
readonly visualize: Record<string, string>;
readonly apis: Readonly<{
bulkIndexAlias: string;
byteSizeUnits: string;
createAutoFollowPattern: string;
createFollower: string;
createIndex: string;
createSnapshotLifecyclePolicy: string;
createRoleMapping: string;
createRoleMappingTemplates: string;
createRollupJobsRequest: string;
createApiKey: string;
createPipeline: string;
createTransformRequest: string;
cronExpressions: string;
executeWatchActionModes: string;
indexExists: string;
openIndex: string;
putComponentTemplate: string;
painlessExecute: string;
painlessExecuteAPIContexts: string;
putComponentTemplateMetadata: string;
putSnapshotLifecyclePolicy: string;
putIndexTemplateV1: string;
putWatch: string;
simulatePipeline: string;
timeUnits: string;
updateTransform: string;
}>;
readonly observability: Readonly<{
guide: string;
infrastructureThreshold: string;
logsThreshold: string;
metricsThreshold: string;
monitorStatus: string;
monitorUptime: string;
tlsCertificate: string;
uptimeDurationAnomaly: string;
}>;
readonly alerting: Record<string, string>;
readonly maps: Record<string, string>;
readonly monitoring: Record<string, string>;
readonly security: Readonly<{
apiKeyServiceSettings: string;
clusterPrivileges: string;
elasticsearchSettings: string;
elasticsearchEnableSecurity: string;
elasticsearchEnableApiKeys: string;
indicesPrivileges: string;
kibanaTLS: string;
kibanaPrivileges: string;
mappingRoles: string;
mappingRolesFieldRules: string;
runAsPrivilege: string;
}>;
readonly spaces: Readonly<{
kibanaLegacyUrlAliases: string;
kibanaDisableLegacyUrlAliasesApi: string;
}>;
readonly watcher: Record<string, string>;
readonly ccs: Record<string, string>;
readonly plugins: Record<string, string>;
readonly snapshotRestore: Record<string, string>;
readonly ingest: Record<string, string>;
readonly fleet: Readonly<{
datastreamsILM: string;
beatsAgentComparison: string;
guide: string;
fleetServer: string;
fleetServerAddFleetServer: string;
settings: string;
settingsFleetServerHostSettings: string;
troubleshooting: string;
elasticAgent: string;
datastreams: string;
datastreamsNamingScheme: string;
installElasticAgent: string;
upgradeElasticAgent: string;
upgradeElasticAgent712lower: string;
learnMoreBlog: string;
apiKeysLearnMore: string;
}>;
readonly ecs: {
readonly guide: string;
};
readonly clients: {
readonly guide: string;
readonly goOverview: string;
readonly javaIndex: string;
readonly jsIntro: string;
readonly netGuide: string;
readonly perlGuide: string;
readonly phpGuide: string;
readonly pythonGuide: string;
readonly rubyOverview: string;
readonly rustGuide: string;
};
readonly endpoints: {
readonly troubleshooting: string;
};
} | | diff --git a/docs/development/core/public/kibana-plugin-core-public.overlayflyoutopenoptions.maskprops.md b/docs/development/core/public/kibana-plugin-core-public.overlayflyoutopenoptions.maskprops.md new file mode 100644 index 0000000000000..3cb3e0b4902a9 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.overlayflyoutopenoptions.maskprops.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [OverlayFlyoutOpenOptions](./kibana-plugin-core-public.overlayflyoutopenoptions.md) > [maskProps](./kibana-plugin-core-public.overlayflyoutopenoptions.maskprops.md) + +## OverlayFlyoutOpenOptions.maskProps property + +Signature: + +```typescript +maskProps?: EuiOverlayMaskProps; +``` diff --git a/docs/development/core/public/kibana-plugin-core-public.overlayflyoutopenoptions.md b/docs/development/core/public/kibana-plugin-core-public.overlayflyoutopenoptions.md index dcecdeb840869..611b2206bccdc 100644 --- a/docs/development/core/public/kibana-plugin-core-public.overlayflyoutopenoptions.md +++ b/docs/development/core/public/kibana-plugin-core-public.overlayflyoutopenoptions.md @@ -20,6 +20,7 @@ export interface OverlayFlyoutOpenOptions | [className](./kibana-plugin-core-public.overlayflyoutopenoptions.classname.md) | string | | | [closeButtonAriaLabel](./kibana-plugin-core-public.overlayflyoutopenoptions.closebuttonarialabel.md) | string | | | [hideCloseButton](./kibana-plugin-core-public.overlayflyoutopenoptions.hideclosebutton.md) | boolean | | +| [maskProps](./kibana-plugin-core-public.overlayflyoutopenoptions.maskprops.md) | EuiOverlayMaskProps | | | [maxWidth](./kibana-plugin-core-public.overlayflyoutopenoptions.maxwidth.md) | boolean | number | string | | | [onClose](./kibana-plugin-core-public.overlayflyoutopenoptions.onclose.md) | (flyout: OverlayRef) => void | EuiFlyout onClose handler. If provided the consumer is responsible for calling flyout.close() to close the flyout; | | [ownFocus](./kibana-plugin-core-public.overlayflyoutopenoptions.ownfocus.md) | boolean | | diff --git a/docs/user/alerting/rule-types.asciidoc b/docs/user/alerting/rule-types.asciidoc index 4c1d3b94bdee6..ab2349f2fb102 100644 --- a/docs/user/alerting/rule-types.asciidoc +++ b/docs/user/alerting/rule-types.asciidoc @@ -26,6 +26,9 @@ see {subscriptions}[the subscription page]. | <> | Run a user-configured {es} query, compare the number of matches to a configured threshold, and schedule actions to run when the threshold condition is met. +| {ref}/transform-alerts.html[{transform-cap} rules] beta:[] +| beta:[] Run scheduled checks on a {ctransform} to check its health. If a {ctransform} meets the conditions, an alert is created and the associated action is triggered. + |=== [float] @@ -47,7 +50,7 @@ Domain rules are registered by *Observability*, *Security*, <> and < | Run an {es} query to determine if any documents are currently contained in any boundaries from a specified boundary index and generate alerts when a rule's conditions are met. | {ml-docs}/ml-configuring-alerts.html[{ml-cap} rules] beta:[] -| Run scheduled checks on an anomaly detection job to detect anomalies with certain conditions. If an anomaly meets the conditions, an alert is created and the associated action is triggered. +| beta:[] Run scheduled checks on an {anomaly-job} to detect anomalies with certain conditions. If an anomaly meets the conditions, an alert is created and the associated action is triggered. |=== diff --git a/docs/user/dashboard/images/lens_areaChartCumulativeNumberOfSalesOnWeekend_7.16.png b/docs/user/dashboard/images/lens_areaChartCumulativeNumberOfSalesOnWeekend_7.16.png new file mode 100644 index 0000000000000..82e0337ffed39 Binary files /dev/null and b/docs/user/dashboard/images/lens_areaChartCumulativeNumberOfSalesOnWeekend_7.16.png differ diff --git a/docs/user/dashboard/images/lens_areaPercentageNumberOfOrdersByCategory_7.16.png b/docs/user/dashboard/images/lens_areaPercentageNumberOfOrdersByCategory_7.16.png new file mode 100644 index 0000000000000..6addc8bc276e9 Binary files /dev/null and b/docs/user/dashboard/images/lens_areaPercentageNumberOfOrdersByCategory_7.16.png differ diff --git a/docs/user/dashboard/images/lens_barChartCustomTimeInterval_7.16.png b/docs/user/dashboard/images/lens_barChartCustomTimeInterval_7.16.png new file mode 100644 index 0000000000000..3aa5484cb6258 Binary files /dev/null and b/docs/user/dashboard/images/lens_barChartCustomTimeInterval_7.16.png differ diff --git a/docs/user/dashboard/images/lens_barChartDistributionOfNumberField_7.16.png b/docs/user/dashboard/images/lens_barChartDistributionOfNumberField_7.16.png new file mode 100644 index 0000000000000..631477e7d68cc Binary files /dev/null and b/docs/user/dashboard/images/lens_barChartDistributionOfNumberField_7.16.png differ diff --git a/docs/user/dashboard/images/lens_clickAndDragZoom_7.16.gif b/docs/user/dashboard/images/lens_clickAndDragZoom_7.16.gif new file mode 100644 index 0000000000000..65fed435dfa25 Binary files /dev/null and b/docs/user/dashboard/images/lens_clickAndDragZoom_7.16.gif differ diff --git a/docs/user/dashboard/images/lens_end_to_end_2_1_1.png b/docs/user/dashboard/images/lens_end_to_end_2_1_1.png index e996b58520d41..f1bee569f29c2 100644 Binary files a/docs/user/dashboard/images/lens_end_to_end_2_1_1.png and b/docs/user/dashboard/images/lens_end_to_end_2_1_1.png differ diff --git a/docs/user/dashboard/images/lens_end_to_end_6_1.png b/docs/user/dashboard/images/lens_end_to_end_6_1.png index 73299bac0354e..942c4d636d1fc 100644 Binary files a/docs/user/dashboard/images/lens_end_to_end_6_1.png and b/docs/user/dashboard/images/lens_end_to_end_6_1.png differ diff --git a/docs/user/dashboard/images/lens_indexPatternDropDown_7.16.png b/docs/user/dashboard/images/lens_indexPatternDropDown_7.16.png new file mode 100644 index 0000000000000..f8e797c7dd4b6 Binary files /dev/null and b/docs/user/dashboard/images/lens_indexPatternDropDown_7.16.png differ diff --git a/docs/user/dashboard/images/lens_index_pattern.png b/docs/user/dashboard/images/lens_index_pattern.png deleted file mode 100644 index 0c89e7ab7f814..0000000000000 Binary files a/docs/user/dashboard/images/lens_index_pattern.png and /dev/null differ diff --git a/docs/user/dashboard/images/lens_layerVisualizationTypeMenu_7.16.png b/docs/user/dashboard/images/lens_layerVisualizationTypeMenu_7.16.png new file mode 100644 index 0000000000000..6ee73e9a67662 Binary files /dev/null and b/docs/user/dashboard/images/lens_layerVisualizationTypeMenu_7.16.png differ diff --git a/docs/user/dashboard/images/lens_leftAxisMenu_7.16.png b/docs/user/dashboard/images/lens_leftAxisMenu_7.16.png new file mode 100644 index 0000000000000..054731adbeef5 Binary files /dev/null and b/docs/user/dashboard/images/lens_leftAxisMenu_7.16.png differ diff --git a/docs/user/dashboard/images/lens_lineChartMetricOverTime_7.16.png b/docs/user/dashboard/images/lens_lineChartMetricOverTime_7.16.png new file mode 100644 index 0000000000000..34fd8dae1407d Binary files /dev/null and b/docs/user/dashboard/images/lens_lineChartMetricOverTime_7.16.png differ diff --git a/docs/user/dashboard/images/lens_lineChartMultipleDataSeries_7.16.png b/docs/user/dashboard/images/lens_lineChartMultipleDataSeries_7.16.png new file mode 100644 index 0000000000000..373fc76b5db41 Binary files /dev/null and b/docs/user/dashboard/images/lens_lineChartMultipleDataSeries_7.16.png differ diff --git a/docs/user/dashboard/images/lens_logsDashboard_7.16.png b/docs/user/dashboard/images/lens_logsDashboard_7.16.png new file mode 100644 index 0000000000000..cdfe0accdbbb5 Binary files /dev/null and b/docs/user/dashboard/images/lens_logsDashboard_7.16.png differ diff --git a/docs/user/dashboard/images/lens_metricUniqueCountOfClientip_7.16.png b/docs/user/dashboard/images/lens_metricUniqueCountOfClientip_7.16.png new file mode 100644 index 0000000000000..bed6acf501a3a Binary files /dev/null and b/docs/user/dashboard/images/lens_metricUniqueCountOfClientip_7.16.png differ diff --git a/docs/user/dashboard/images/lens_metricUniqueVisitors_7.16.png b/docs/user/dashboard/images/lens_metricUniqueVisitors_7.16.png new file mode 100644 index 0000000000000..92fe4fb0676f2 Binary files /dev/null and b/docs/user/dashboard/images/lens_metricUniqueVisitors_7.16.png differ diff --git a/docs/user/dashboard/images/lens_mixedXYChart_7.16.png b/docs/user/dashboard/images/lens_mixedXYChart_7.16.png new file mode 100644 index 0000000000000..76fc96a44a402 Binary files /dev/null and b/docs/user/dashboard/images/lens_mixedXYChart_7.16.png differ diff --git a/docs/user/dashboard/images/lens_pieChartCompareSubsetOfDocs_7.16.png b/docs/user/dashboard/images/lens_pieChartCompareSubsetOfDocs_7.16.png new file mode 100644 index 0000000000000..f8e8ba98f691e Binary files /dev/null and b/docs/user/dashboard/images/lens_pieChartCompareSubsetOfDocs_7.16.png differ diff --git a/docs/user/dashboard/images/lens_referenceLine_7.16.png b/docs/user/dashboard/images/lens_referenceLine_7.16.png new file mode 100644 index 0000000000000..3df7e99e0aafe Binary files /dev/null and b/docs/user/dashboard/images/lens_referenceLine_7.16.png differ diff --git a/docs/user/dashboard/images/lens_tableTopFieldValues_7.16.png b/docs/user/dashboard/images/lens_tableTopFieldValues_7.16.png new file mode 100644 index 0000000000000..64417a9a6392c Binary files /dev/null and b/docs/user/dashboard/images/lens_tableTopFieldValues_7.16.png differ diff --git a/docs/user/dashboard/images/lens_timeSeriesDataTutorialDashboard_7.16.png b/docs/user/dashboard/images/lens_timeSeriesDataTutorialDashboard_7.16.png new file mode 100644 index 0000000000000..bce904c8606ca Binary files /dev/null and b/docs/user/dashboard/images/lens_timeSeriesDataTutorialDashboard_7.16.png differ diff --git a/docs/user/dashboard/images/lens_treemapMultiLevelChart_7.16.png b/docs/user/dashboard/images/lens_treemapMultiLevelChart_7.16.png new file mode 100644 index 0000000000000..6d772a32e9ef4 Binary files /dev/null and b/docs/user/dashboard/images/lens_treemapMultiLevelChart_7.16.png differ diff --git a/docs/user/dashboard/images/lens_visualizationTypeDropdown_7.16.png b/docs/user/dashboard/images/lens_visualizationTypeDropdown_7.16.png new file mode 100644 index 0000000000000..dce53da1f2cad Binary files /dev/null and b/docs/user/dashboard/images/lens_visualizationTypeDropdown_7.16.png differ diff --git a/docs/user/dashboard/lens-advanced.asciidoc b/docs/user/dashboard/lens-advanced.asciidoc index 02e0afd2c0311..324676ecb0a8e 100644 --- a/docs/user/dashboard/lens-advanced.asciidoc +++ b/docs/user/dashboard/lens-advanced.asciidoc @@ -2,18 +2,21 @@ == Analyze time series data In this tutorial, you'll use the ecommerce sample data to analyze sales trends, but you can use any type of data to complete the tutorial. -Before using this tutorial, review the <>. + +When you're done, you'll have a complete overview of the sample web logs data. [role="screenshot"] -image::images/final_time_series_analysis_dashboard.png[Final dashboard with ecommerce sample data, width=50%] +image::images/lens_timeSeriesDataTutorialDashboard_7.16.png[Final dashboard with ecommerce sample data] + +Before you begin, you should be familiar with the <>. [discrete] [[add-the-data-and-create-the-dashboard-advanced]] === Add the data and create the dashboard -Add the sample ecommerce data that you'll use to create the dashboard panels. +Add the sample ecommerce data, and create and set up the dashboard. -. Go to the {kib} *Home* page, then click *Try our sample data*. +. Go to the *Home* page, then click *Try sample data*. . On the *Sample eCommerce orders* card, click *Add data*. @@ -25,40 +28,30 @@ Create the dashboard where you'll display the visualization panels. [float] [[open-and-set-up-lens-advanced]] -=== Open and set up Lens +=== Open and set up the visualization editor -Open *Lens*, then make sure the correct fields appear. +Open the visualization editor, then make sure the correct fields appear. -. From the dashboard, click *Create visualization*. +. On the dashboard, click *Create visualization*. -. Make sure the *kibana_sample_data_ecommerce* index appears. -+ -If you are using your own data, select the <> that contains your data. +. Make sure the *kibana_sample_data_ecommerce* index appears, then set the <> to *Last 30 days*. [discrete] [[custom-time-interval]] -=== View a date histogram with a custom time interval - -It is common to use the automatic date histogram interval, but sometimes you want a larger or smaller -interval. For performance reasonse, *Lens* lets you choose the minimum time interval, not the exact time interval. The performance limit is controlled by the <> setting and the <>. +=== Create visualizations with custom time intervals -If you are using your own data, use one of the following options to see hourly sales over the last 30 days: +When you create visualizations with time series data, you can use the default time interval, or increase and decrease the interval. For performance reasons, the visualization editor allows you to choose the minimum time interval, but not the exact time interval. The interval limit is controlled by the <> setting and <>. -* View less than 30 days at a time, then use the time filter to select each day separately. - -* Increase `histogram:maxBars` to at least 720, which is the number of hours in 30 days. This affects all visualizations and can reduce performance. - -If you are using the sample data, use *Normalize unit*, which converts *Average sales per 12 hours* -into *Average sales per 12 hours (per hour)* by dividing the number of hours: - -. Set the <> to *Last 30 days*. +To analyze the data with a custom time interval, create a bar chart that shows you how many orders were made at your store every hour: . From the *Available fields* list, drag *Records* to the workspace. ++ +The visualization editor creates a bar chart. -. To zoom in on the data you want to view, click and drag your cursor across the bars. +. To zoom in on the data, click and drag your cursor across the bars. + [role="screenshot"] -image::images/lens_advanced_1_1.png[Added records to the workspace] +image::images/lens_clickAndDragZoom_7.16.gif[Cursor clicking and dragging across the bars to zoom in on the data] . In the layer pane, click *Count of Records*. @@ -67,32 +60,51 @@ image::images/lens_advanced_1_1.png[Added records to the workspace] .. Click *Add advanced options > Normalize by unit*. .. From the *Normalize by unit* dropdown, select *per hour*, then click *Close*. ++ +*Normalize unit* converts *Average sales per 12 hours* into *Average sales per 12 hours (per hour)* by dividing the number of hours. . To hide the *Horizontal axis* label, open the *Bottom Axis* menu, then deselect *Show*. -+ -You have a bar chart that shows you how many orders were made at your store every hour. + +To identify the 75th percentile of orders, add a reference line: + +. In the layer pane, click *Add layer > Add reference layer*. + +. Click *Static value*. + +. Click the *Percentile* function, then enter `75` in the *Percentile* field. + +. Configure the display options. + +.. In the *Display name* field, enter `75th`. + +.. Select *Show display name*. + +.. From the *Icon* dropdown, select *Tag*. + +.. In the *Color* field, enter `#E7664C`. + +. Click *Close*. + [role="screenshot"] -image::images/lens_advanced_1_2.png[Orders per day] +image::images/lens_barChartCustomTimeInterval_7.16.png[Orders per day] . Click *Save and return*. [discrete] [[add-a-data-layer-advanced]] -=== Monitor multiple series +=== Analyze multiple data series -It is often required to monitor multiple series within a time interval. These series can have similar configurations with minor differences. -*Lens* copies a function when you drag it to the *Drop a field or click to add* field within the same group. +You can create visualizations with multiple data series within the same time interval, even when the series have similar configurations with minor differences. -To quickly create many copies of a percentile metric that shows distribution of price over time: +To analyze multiple series, create a line chart that displays the price distribution of products sold over time: . On the dashboard, click *Create visualization*. -. Open the *Chart Type* dropdown, then select *Line*. +. Open the *Visualization type* dropdown, then select *Line*. . From the *Available fields* list, drag *products.price* to the workspace. -Create the 95th percentile. +Create the 95th price distribution percentile: . In the layer pane, click *Median of products.price*. @@ -100,9 +112,9 @@ Create the 95th percentile. . In the *Display name* field, enter `95th`, then click *Close*. -To create the 90th percentile, duplicate the `95th` percentile. +To copy a function, you drag it to the *Drop a field or click to add* field within the same group. To create the 90th percentile, duplicate the `95th` percentile: -. Drag the *95th* field to the *Drop a field or click to add* field in the *Vertical axis* group. +. Drag the *95th* field to *Add or drag-and-drop a field* for *Vertical axis*. + [role="screenshot"] image::images/lens_advanced_2_2.gif[Easily duplicate the items with drag and drop] @@ -111,22 +123,22 @@ image::images/lens_advanced_2_2.gif[Easily duplicate the items with drag and dro . In the *Display name* field enter `90th`, then click *Close*. -. Repeat the duplication steps to create the `50th` and `10th` percentiles. +. To create the `50th` and `10th` percentiles, repeat the duplication steps. . Open the *Left Axis* menu, then enter `Percentiles for product prices` in the *Axis name* field. + -You have a line chart that shows you the price distribution of products sold over time. -+ [role="screenshot"] -image::images/lens_advanced_2_3.png[Percentiles for product prices chart] +image::images/lens_lineChartMultipleDataSeries_7.16.png[Percentiles for product prices chart] . Click *Save and return*. [discrete] [[add-a-data-layer]] -==== Add multiple chart types or index patterns +=== Analyze multiple visualization types + +With layers, you can analyze your data with multiple visualization types. When you create layered visualizations, match the data on the horizontal axis so that it uses the same scale. -To overlay visualization types or index patterns, add layers. When you create layered charts, match the data on the horizontal axis so that it uses the same scale. +To analyze multiple visualization types, create an area chart that displays the average order prices, then add a line chart layer that displays the number of customers. . On the dashboard, click *Create visualization*. @@ -136,19 +148,19 @@ To overlay visualization types or index patterns, add layers. When you create la .. Click the *Average* function. -.. In the *Display name* field, enter `Average of prices`, then click *Close*. +.. In the *Display name* field, enter `Average price`, then click *Close*. -. Open the *Chart Type* dropdown, then select *Area*. +. Open the *Visualization type* dropdown, then select *Area*. -Create a new layer to overlay with custom traffic. +Add a layer to display the customer traffic: -. In the layer pane, click *+*. +. In the layer pane, click *Add layer > Add visualization layer*. . From the *Available fields* list, drag *customer_id* to the *Vertical Axis* field in the second layer. -. In the second layer, click *Unique count of customer_id*. +. In the layer pane, click *Unique count of customer_id*. -.. In the *Display name* field, enter `Unique customers`. +.. In the *Display name* field, enter `Number of customers`. .. In the *Series color* field, enter *#D36086*. @@ -156,12 +168,15 @@ Create a new layer to overlay with custom traffic. . From the *Available fields* list, drag *order_date* to the *Horizontal Axis* field in the second layer. -. In the second layer pane, open the *Chart type* menu, then click the line chart. +. In the second layer, open the *Layer visualization type* menu, then click *Line*. + [role="screenshot"] -image::images/lens_advanced_3_2.png[Change layer type] +image::images/lens_layerVisualizationTypeMenu_7.16.png[Layer visualization type menu] -. Open the *Legend* menu, then select the arrow that points up. +. To change the position of the legend, open the *Legend* menu, then select the *Alignment* arrow that points up. ++ +[role="screenshot"] +image::images/lens_mixedXYChart_7.16.png[Layer visualization type menu] . Click *Save and return*. @@ -169,35 +184,35 @@ image::images/lens_advanced_3_2.png[Change layer type] [[percentage-stacked-area]] === Compare the change in percentage over time -By default, *Lens* shows *date histograms* using a stacked chart visualization, which helps understand how distinct sets of documents perform over time. Sometimes it is useful to understand how the distributions of these sets change over time. -Combine *filters* and *date histogram* functions to see the change over time in specific -sets of documents. To view this as a percentage, use a *Stacked percentage* bar or area chart. +By default, the visualization editor displays time series data with stacked charts, which show how the different document sets change over time. + +To view change over time as a percentage, create an *Area percentage* chart that displays three order categories over time: . On the dashboard, click *Create visualization*. . From the *Available fields* list, drag *Records* to the workspace. -. Open the *Chart type* dropdown, then select *Area percentage*. +. Open the *Visualization type* dropdown, then select *Area percentage*. -For each category type, create a filter. +For each order category, create a filter: -. In the layer pane, click the *Drop a field or click to add* field for *Break down by*. +. In the layer pane, click *Add or drag-and-drop a field* for *Break down by*. . Click the *Filters* function. -. Click *All records*, enter the following, then press Return: +. Click *All records*, enter the following in the query bar, then press Return: * *KQL* — `category.keyword : *Clothing` * *Label* — `Clothing` -. Click *Add a filter*, enter the following, then press Return: +. Click *Add a filter*, enter the following in the query bar, then press Return: * *KQL* — `category.keyword : *Shoes` * *Label* — `Shoes` -. Click *Add a filter*, enter the following, then press Return: +. Click *Add a filter*, enter the following in the query bar, then press Return: * *KQL* — `category.keyword : *Accessories` @@ -205,10 +220,10 @@ For each category type, create a filter. . Click *Close*. -. Open the *Legend* menu, then select the arrow that points up. +. Open the *Legend* menu, then select the *Alignment* arrow that points up. + [role="screenshot"] -image::images/lens_advanced_4_1.png[Prices share by category] +image::images/lens_areaPercentageNumberOfOrdersByCategory_7.16.png[Prices share by category] . Click *Save and return*. @@ -220,9 +235,9 @@ To determine the number of orders made only on Saturday and Sunday, create an ar . On the dashboard, click *Create visualization*. -. Open the *Chart Type* dropdown, then select *Area*. +. Open the *Visualization type* dropdown, then select *Area*. -Configure the cumulative sum of the store orders. +Configure the cumulative sum of store orders: . From the *Available fields* list, drag *Records* to the workspace. @@ -230,15 +245,15 @@ Configure the cumulative sum of the store orders. . Click the *Cumulative sum* function. -. In the *Display name* field, enter `Cumulative orders during weekend days`, then click *Close*. +. In the *Display name* field, enter `Cumulative weekend orders`, then click *Close*. -Filter the results to display the data for only Saturday and Sunday. +Filter the results to display the data for only Saturday and Sunday: -. In the layer pane, click the *Drop a field or click to add* field for *Break down by*. +. In the layer pane, click *Add or drag-and-drop a field* for *Break down by*. . Click the *Filters* function. -. Click *All records*, enter the following, then press Return: +. Click *All records*, enter the following in the query bar, then press Return: * *KQL* — `day_of_week : "Saturday" or day_of_week : "Sunday"` @@ -249,7 +264,7 @@ The <> displays all documents where `day_of_week` matche . Open the *Legend* menu, then click *Hide*. + [role="screenshot"] -image::images/lens_advanced_5_2.png[Line chart with cumulative sum of orders made on the weekend] +image::images/lens_areaChartCumulativeNumberOfSalesOnWeekend_7.16.png[Area chart with cumulative sum of orders made on the weekend] . Click *Save and return*. @@ -257,30 +272,25 @@ image::images/lens_advanced_5_2.png[Line chart with cumulative sum of orders mad [[compare-time-ranges]] === Compare time ranges -*Lens* allows you to compare the selected time range with historical data using the *Time shift* option. +With *Time shift*, you can compare the data from different time ranges. To make sure the data correctly displays, choose a multiple of the date histogram interval when you use multiple time shifts. For example, you are unable to use a *36h* time shift for one series, and a *1d* time shift for the second series if the interval is *days*. -If multiple time shifts are used in a single chart, a multiple of the date histogram interval should be chosen, or the data points might not line up and gaps can appear. -For example, if a daily interval is used, shifting one series by *36h*, and another by *1d* is not recommended. You can reduce the interval to *12h*, or create two separate charts. - -To compare current sales numbers with sales from a week ago, follow these steps: +To compare two time ranges, create a line chart that compares the sales in the current week with sales from the previous week: . On the dashboard, click *Create visualization*. -. Open the *Chart Type* dropdown, then select *Line*. +. Open the *Visualization type* dropdown, then select *Line*. . From the *Available fields* list, drag *Records* to the workspace. -. In the layer pane, drag *Count of Records* to the *Drop a field or click to add* field in the *Vertical axis* group. +. To duplicate *Count of Records*, drag *Count of Records* to *Add or drag-and-drop a field* for *Vertical axis* in the layer pane. -To create a week-over-week comparison, shift the second *Count of Records* by one week. +To create a week-over-week comparison, shift *Count of Records [1]* by one week: . In the layer pane, click *Count of Records [1]*. -. Open the *Add advanced options* dropdown, then select *Time shift*. - -. Click *1 week ago*. +. Click *Add advanced options > Time shift*, select *1 week ago*, then click *Close*. + -To define custom time shifts, enter the time value, the time increment, then press Enter. For example, to use a one week time shift, enter *1w*. +To use custom time shifts, enter the time value and increment, then press Enter. For example, enter *1w* to use the *1 week ago* time shift. + [role="screenshot"] image::images/lens_time_shift.png[Line chart with week-over-week sales comparison] @@ -289,9 +299,11 @@ image::images/lens_time_shift.png[Line chart with week-over-week sales compariso [float] [[compare-time-as-percent]] -==== Compare time ranges as a percent change +==== Analyze the percent change between time ranges -To view the percent change in sales between the current time and the previous week, create a *Formula*. +With *Formula*, you can analyze the percent change in your data from different time ranges. + +To compare time range changes as a percent, create a bar chart that compares the sales in the current week with sales from the previous week: . On the dashboard, click *Create visualization*. @@ -299,11 +311,11 @@ To view the percent change in sales between the current time and the previous we . In the layer pane, click *Count of Records*. -.. Click *Formula*, then enter `count() / count(shift='1w') - 1`. +. Click *Formula*, then enter `count() / count(shift='1w') - 1`. -.. Open the *Value format* dropdown, select *Percent*, then enter `0` in the *D*ecimals* field. +. Open the *Value format* dropdown, select *Percent*, then enter `0` in the *Decimals* field. -.. In the *Display name* field, enter `Percent change`, then click *Close*. +. In the *Display name* field, enter `Percent of change`, then click *Close*. + [role="screenshot"] image::images/lens_percent_chage.png[Bar chart with percent change in sales between the current time and the previous week] @@ -312,34 +324,33 @@ image::images/lens_percent_chage.png[Bar chart with percent change in sales betw [discrete] [[view-customers-over-time-by-continents]] -=== Create a table of customers by category over time +=== Analyze the data in a table -Tables are useful when you want to display the actual field values. -You can build a date histogram table, and group the customer count metric by category, such as the continent registered in user accounts. +With tables, you can view and compare the field values, which is useful for displaying the locations of customer orders. -In *Lens* you can split the metric in a table leveraging the *Columns* field, where each data value from the aggregation is used as column of the table and the relative metric value is shown. +Create a date histogram table and group the customer count metric by category, such as the continent registered in user accounts: . On the dashboard, click *Create visualization*. -. Open the *Chart Type* dropdown, then click *Table*. +. Open the *Visualization type* dropdown, then select *Table*. . From the *Available fields* list, drag *customer_id* to the *Metrics* field in the layer pane. -. In the layer pane, click *Unique count of customer_id*. +.. In the layer pane, click *Unique count of customer_id*. -. In the *Display name* field, enter `Customers`, then click *Close*. +.. In the *Display name* field, enter `Customers`, then click *Close*. . From the *Available fields* list, drag *order_date* to the *Rows* field in the layer pane. -. In the layer pane, click the *order_date*. +.. In the layer pane, click the *order_date*. .. Select *Customize time interval*. .. Change the *Minimum interval* to *1 days*. -.. In the *Display name* field, enter `Sale`, then click *Close*. +.. In the *Display name* field, enter `Sales`, then click *Close*. -Add columns for each continent. +To split the metric, add columns for each continent using the *Columns* field: . From the *Available fields* list, drag *geoip.continent_name* to the *Columns* field in the layer pane. + @@ -360,3 +371,6 @@ Now that you have a complete overview of your ecommerce sales data, save the das . Select *Store time with dashboard*. . Click *Save*. + +[role="screenshot"] +image::images/lens_timeSeriesDataTutorialDashboard_7.16.png[Final dashboard with ecommerce sample data] diff --git a/docs/user/dashboard/lens.asciidoc b/docs/user/dashboard/lens.asciidoc index c3e0a5523a78d..23a6d1fbcfd3d 100644 --- a/docs/user/dashboard/lens.asciidoc +++ b/docs/user/dashboard/lens.asciidoc @@ -48,6 +48,8 @@ Choose the data you want to visualize. . If you want to learn more about the data a field contains, click the field. +. To visualize more than one index pattern, click *Add layer > Add visualization layer*, then select the index pattern. + Edit and delete. . To change the aggregation *Quick function* and display options, click the field in the layer pane. @@ -60,11 +62,11 @@ Edit and delete. Change the fields list to display a different index pattern, different time range, or add your own fields. -* To create a visualization with fields in a different index pattern, open the *Change index pattern* dropdown, then select the index pattern. +* To create a visualization with fields in a different index pattern, open the *Index pattern* dropdown, then select the index pattern. * If the fields list is empty, change the <>. -* To add fields, open the action menu (*...*) next to the *Change index pattern* dropdown, then select *Add field to index pattern*. +* To add fields, open the action menu (*...*) next to the *Index pattern* dropdown, then select *Add field to index pattern*. + [role="screenshot"] image:images/runtime-field-menu.png[Dropdown menu located next to index pattern field with items for adding and managing fields, width=50%] @@ -176,6 +178,29 @@ Compare your real-time data set to the results that are offset by a time increme For a time shift example, refer to <>. +[float] +[[add-reference-lines]] +==== Add reference lines + +With reference lines, you can identify specific values in your visualizations with icons, colors, and other display options. You can add reference lines to any visualization type that displays axes. + +For example, to track the number of bytes in the 75th percentile, add a shaded *Percentile* reference line to your time series visualization. + +[role="screenshot"] +image::images/lens_referenceLine_7.16.png[Lens drag and drop focus state] + +. In the layer pane, click *Add layer > Add reference layer*. + +. Click the reference line value, then specify the reference line you want to use: + +* To add a static reference line, click *Static*, then enter the reference line value you want to use. + +* To add a dynamic reference line, click *Quick functions*, then click and configure the functions you want to use. + +* To calculate the reference line value with math, click *Formula*, then enter the formula. + +. Specify the display options, such as *Display name* and *Icon*, then click *Close*. + [float] [[filter-the-data]] ==== Apply filters @@ -236,9 +261,29 @@ The following component menus are available: * *Left axis*, *Bottom axis*, and *Right axis* — Specify how you want to display the chart axes. For example, add axis labels and change the orientation and bounds. +[float] +[[view-data-and-requests]] +==== View the visualization data and requests + +To view the data included in the visualization and the requests that collected the data, use the *Inspector*. + +. In the toolbar, click *Inspect*. + +. Open the *View* dropdown, then click *Data*. + +.. From the dropdown, select the table that contains the data you want to view. + +.. To download the data, click *Download CSV*, then select the format type. + +. Open the *View* dropdown, then click *Requests*. + +.. From the dropdown, select the requests you want to view. + +.. To view the requests in *Console*, click *Request*, then click *Open in Console*. + [float] [[save-the-lens-panel]] -===== Save and add the panel +==== Save and add the panel Save the panel to the *Visualize Library* and add it to the dashboard, or add it to the dashboard without saving. @@ -408,7 +453,7 @@ To configure the bounds, use the menus in the editor toolbar. Bar and area chart .*Is it possible to display icons in data tables?* [%collapsible] ==== -You can display icons with <> in data tables. +You can display icons with <> in data tables. ==== [discrete] diff --git a/docs/user/dashboard/tutorial-create-a-dashboard-of-lens-panels.asciidoc b/docs/user/dashboard/tutorial-create-a-dashboard-of-lens-panels.asciidoc index c3d76ee88322b..e270c16cf60f6 100644 --- a/docs/user/dashboard/tutorial-create-a-dashboard-of-lens-panels.asciidoc +++ b/docs/user/dashboard/tutorial-create-a-dashboard-of-lens-panels.asciidoc @@ -1,21 +1,24 @@ [[create-a-dashboard-of-panels-with-web-server-data]] -== Build your first dashboard +== Create your first dashboard -Learn the most common ways to build a dashboard from your own data. +Learn the most common ways to create a dashboard from your own data. The tutorial will use sample data from the perspective of an analyst looking at website logs, but this type of dashboard works on any type of data. -Before using this tutorial, you should be familiar with the <>. + +When you're done, you'll have a complete overview of the sample web logs data. [role="screenshot"] -image::images/lens_end_to_end_dashboard.png[Final dashboard vis] +image::images/lens_logsDashboard_7.16.png[Logs dashboard] + +Before you begin, you should be familiar with the <>. [discrete] [[add-the-data-and-create-the-dashboard]] === Add the data and create the dashboard -Add the sample web logs data that you'll use to create the dashboard panels. +Add the sample web logs data, and create and set up the dashboard. -. Go to the {kib} *Home* page, then click *Try our sample data*. +. Go to the *Home* page, then click *Try sample data*. . On the *Sample web logs* card, click *Add data*. @@ -29,56 +32,70 @@ Create the dashboard where you'll display the visualization panels. [float] [[open-and-set-up-lens]] -=== Open Lens and get familiar with the data +=== Open the visualization editor and get familiar with the data + +Open the visualization editor, then make sure the correct fields appear. . On the dashboard, click *Create visualization*. . Make sure the *kibana_sample_data_logs* index appears. + [role="screenshot"] -image::images/lens_end_to_end_1_2.png[Lens index pattern selector, width=50%] +image::images/lens_indexPatternDropDown_7.16.png[Index pattern dropdown] + +To create the visualizations in this tutorial, you'll use the following fields: + +* *Records* -. To create the visualizations in this tutorial, you'll use the *Records*, *timestamp*, *bytes*, *clientip*, and *referer.keyword* fields. To see the most frequent values of a field, hover over the field name, then click *i*. +* *timestamp* + +* *bytes* + +* *clientip* + +* *referer.keyword* + +To see the most frequent values in a field, hover over the field name, then click *i*. [discrete] [[view-the-number-of-website-visitors]] === Create your first visualization -Pick a field you want to analyze, such as *clientip*. If you want -to analyze only this field, you can use the *Metric* visualization to display a big number. -The only number function that you can use with *clientip* is *Unique count*. -*Unique count*, also referred to as cardinality, approximates the number of unique values -of the *clientip* field. +Pick a field you want to analyze, such as *clientip*. To analyze only the *clientip* field, use the *Metric* visualization to display the field as a number. + +The only number function that you can use with *clientip* is *Unique count*, also referred to as cardinality, which approximates the number of unique values. -. To select the visualization type, open the *Chart type* dropdown, then select *Metric*. +. Open the *Visualization type* dropdown, then select *Metric*. + [role="screenshot"] -image::images/lens_end_to_end_1_2_1.png[Chart Type dropdown with Metric selected, width=50%] +image::images/lens_visualizationTypeDropdown_7.16.png[Visualization type dropdown] -. From the *Available fields* list, drag *clientip* to the workspace. +. From the *Available fields* list, drag *clientip* to the workspace or layer pane. + [role="screenshot"] -image::images/lens_end_to_end_1_3.png[Changed type and dropped clientip field] +image::images/lens_metricUniqueCountOfClientip_7.16.png[Metric visualization of the clientip field] + -*Lens* selects the *Unique count* function because it is the only numeric function -that works for IP addresses. You can also drag *clientip* to the layer pane for the same result. +In the layer pane, *Unique count of clientip* appears because the editor automatically applies the *Unique count* function to the *clientip* field. *Unique count* is the only numeric function that works with IP addresses. . In the layer pane, click *Unique count of clientip*. .. In the *Display name* field, enter `Unique visitors`. .. Click *Close*. ++ +[role="screenshot"] +image::images/lens_metricUniqueVisitors_7.16.png[Metric visualization that displays number of unique visitors] . Click *Save and return*. + -The metric visualization has its own label, so you do not need to add a panel title. +*[No Title]* appears in the visualization panel header. Since the visualization has its own `Unique visitors` label, you do not need to add a panel title. [discrete] [[mixed-multiaxis]] === View a metric over time -*Lens* has two shortcuts that simplify viewing metrics over time. -If you drag a numeric field to the workspace, *Lens* adds the default +There are two shortcuts you can use to view metrics over time. +When you drag a numeric field to the workspace, the visualization editor adds the default time field from the index pattern. When you use the *Date histogram* function, you can replace the time field by dragging the field to the workspace. @@ -88,78 +105,76 @@ To visualize the *bytes* field over time: . From the *Available fields* list, drag *bytes* to the workspace. + -*Lens* creates a bar chart with the *timestamp* and *Median of bytes* fields, and automatically chooses a date interval. +The visualization editor creates a bar chart with the *timestamp* and *Median of bytes* fields. -. To zoom in on the data you want to view, click and drag your cursor across the bars. +. To zoom in on the data, click and drag your cursor across the bars. + [role="screenshot"] image::images/lens_end_to_end_3_1_1.gif[Zoom in on the data] -To emphasize the change in *Median of bytes* over time, change to a line chart with one of the following options: - -* From the *Suggestions*, click the line chart. -* Open the *Chart type* dropdown in the editor toolbar, then select *Line*. -* Open the *Chart type* menu in the layer pane, then click the line chart. +To emphasize the change in *Median of bytes* over time, change the visualization type to *Line* with one of the following options: -You can increase and decrease the minimum interval that *Lens* uses, but you are unable to decrease the interval -below the <>. +* In the *Suggestions*, click the line chart. +* In the editor toolbar, open the *Visualization type* dropdown, then select *Line*. +* In the layer pane, open the *Layer visualization type* menu, then click *Line*. -To set the minimum time interval: +To increase the minimum time interval: . In the layer pane, click *timestamp*. . Select *Customize time interval*. . Change the *Minimum interval* to *1 days*, then click *Close*. ++ +You can increase and decrease the minimum interval, but you are unable to decrease the interval below the <>. -To save space on the dashboard, hide the vertical and horizontal axis labels. +To save space on the dashboard, hide the axis labels. . Open the *Left axis* menu, then deselect *Show*. + [role="screenshot"] -image::images/lens_end_to_end_4_3.png[Turn off axis label] +image::images/lens_leftAxisMenu_7.16.png[Left axis menu] . Open the *Bottom axis* menu, then deselect *Show*. ++ +[role="screenshot"] +image::images/lens_lineChartMetricOverTime_7.16.png[Line chart that displays metric data over time] . Click *Save and return* -Add a panel title to explain the panel, which is necessary because you removed the axis labels. +Since you removed the axis labels, add a panel title: -.. Open the panel menu, then select *Edit panel title*. +. Open the panel menu, then select *Edit panel title*. -.. In the *Panel title* field, enter `Median of bytes`, then click *Save*. +. In the *Panel title* field, enter `Median of bytes`, then click *Save*. [discrete] [[view-the-distribution-of-visitors-by-operating-system]] === View the top values of a field +Create a visualization that displays the most frequent values of *request.keyword* on your website, ranked by the unique visitors. +To create the visualization, use *Top values of request.keyword* ranked by *Unique count of clientip*, instead of being ranked by *Count of records*. + The *Top values* function ranks the unique values of a field by another function. The values are the most frequent when ranked by a *Count* function, and the largest when ranked by the *Sum* function. -Create a visualization that displays the most frequent values of *request.keyword* on your website, ranked by the unique visitors. -To create the visualization, use *Top values of request.keyword* ranked by *Unique count of clientip*, instead of -being ranked by *Count of records*. - . On the dashboard, click *Create visualization*. . From the *Available fields* list, drag *clientip* to the *Vertical axis* field in the layer pane. + -*Lens* automatically chooses the *Unique count* function. If you drag *clientip* to the workspace, *Lens* adds the field to the incorrect axis. -+ -When you drag a text or IP address field to the workspace, -*Lens* adds the *Top values* function ranked by *Count of records* to show the most frequent values. +The visualization editor automatically applies the *Unique count* function. If you drag *clientip* to the workspace, the editor adds the field to the incorrect axis. . Drag *request.keyword* to the workspace. + [role="screenshot"] image::images/lens_end_to_end_2_1_1.png[Vertical bar chart with top values of request.keyword by most unique visitors] + -*Lens* adds *Top values of request.keyword* to the *Horizontal axis*. +When you drag a text or IP address field to the workspace, +the editor adds the *Top values* function ranked by *Count of records* to show the most frequent values. -The chart is hard to read because the *request.keyword* field contains long text. You could try -using one of the *Suggestions*, but the suggestions also have issues with long text. Instead, create a *Table* visualization. +The chart labels are unable to display because the *request.keyword* field contains long text fields. You could use one of the *Suggestions*, but the suggestions also have issues with long text. The best way to display long text fields is with the *Table* visualization. -. Open the *Chart type* dropdown, then select *Table*. +. Open the *Visualization type* dropdown, then select *Table*. + [role="screenshot"] image::images/lens_end_to_end_2_1_2.png[Table with top values of request.keyword by most unique visitors] @@ -171,16 +186,19 @@ image::images/lens_end_to_end_2_1_2.png[Table with top values of request.keyword .. In the *Display name* field, enter `Page URL`. .. Click *Close*. ++ +[role="screenshot"] +image::images/lens_tableTopFieldValues_7.16.png[Table that displays the top field values] . Click *Save and return*. + -The table does not need a panel title because the columns are clearly labeled. +Since the table columns are labeled, you do not need to add a panel title. [discrete] [[custom-ranges]] === Compare a subset of documents to all documents -Create a proportional visualization that helps you to determine if your users transfer more bytes from documents under 10KB versus documents over 10 Kb. +Create a proportional visualization that helps you determine if your users transfer more bytes from documents under 10KB versus documents over 10Kb. . On the dashboard, click *Create visualization*. @@ -190,12 +208,14 @@ Create a proportional visualization that helps you to determine if your users tr . From the *Available fields* list, drag *bytes* to the *Break down by* field in the layer pane. -Use the *Intervals* function to select documents based on the number range of a field. -If the ranges were non numeric, or if the query required multiple clauses, you could use the *Filters* function. +To select documents based on the number range of a field, use the *Intervals* function. +When the ranges are non numeric, or the query requires multiple clauses, you could use the *Filters* function. + +Specify the file size ranges: -. To specify the file size ranges, click *bytes* in the layer pane. +. In the layer pane, click *bytes*. -. Click *Create custom ranges*, enter the following, then press Return: +. Click *Create custom ranges*, enter the following in the *Ranges* field, then press Return: * *Ranges* — `0` -> `10240` @@ -214,27 +234,30 @@ image::images/lens_end_to_end_6_1.png[Custom ranges configuration] To display the values as a percentage of the sum of all values, use the *Pie* chart. -. Open the *Chart Type* dropdown, then select *Pie*. +. Open the *Visualization Type* dropdown, then select *Pie*. ++ +[role="screenshot"] +image::images/lens_pieChartCompareSubsetOfDocs_7.16.png[Pie chart that compares a subset of documents to all documents] . Click *Save and return*. -. Add a panel title. +Add a panel title: -.. Open the panel menu, then select *Edit panel title*. +. Open the panel menu, then select *Edit panel title*. -.. In the *Panel title* field, enter `Sum of bytes from large requests`, then click *Save*. +. In the *Panel title* field, enter `Sum of bytes from large requests`, then click *Save*. [discrete] [[histogram]] === View the distribution of a number field -Knowing the distribution of a number helps you find patterns. For example, you can analyze the website traffic per hour to find the best time to do routine maintenance. +The distribution of a number can help you find patterns. For example, you can analyze the website traffic per hour to find the best time for routine maintenance. . On the dashboard, click *Create visualization*. . From the *Available fields* list, drag *bytes* to *Vertical axis* field in the layer pane. -. In the layer pane, click *Median of bytes* +. In the layer pane, click *Median of bytes*. .. Click the *Sum* function. @@ -246,70 +269,80 @@ Knowing the distribution of a number helps you find patterns. For example, you c . In the layer pane, click *hour_of_day*, then slide the *Intervals granularity* slider until the horizontal axis displays hourly intervals. + -The *Intervals* function displays an evenly spaced distribution of the field. +[role="screenshot"] +image::images/lens_barChartDistributionOfNumberField_7.16.png[Bar chart that displays the distribution of a number field] . Click *Save and return*. +Add a panel title: + +. Open the panel menu, then select *Edit panel title*. + +. In the *Panel title* field, enter `Website traffic`, then click *Save*. + [discrete] [[treemap]] === Create a multi-level chart -You can use multiple functions in data tables and proportion charts. For example, -to create a chart that breaks down the traffic sources and user geography, use *Filters* and -*Top values*. +*Table* and *Proportion* visualizations support multiple functions. For example, to create visualizations that break down the data by website traffic sources and user geography, apply the *Filters* and *Top values* functions. . On the dashboard, click *Create visualization*. -. Open the *Chart type* dropdown, then select *Treemap*. +. Open the *Visualization type* dropdown, then select *Treemap*. . From the *Available fields* list, drag *Records* to the *Size by* field in the layer pane. -. In the editor, click the *Drop a field or click to add* field for *Group by*, then create a filter for each website traffic source. +. In the editor, click *Add or drag-and-drop a field* for *Group by*. -.. From *Select a function*, click *Filters*. +Create a filter for each website traffic source: -.. Click *All records*, enter the following, then press Return: +. From *Select a function*, click *Filters*. + +. Click *All records*, enter the following in the query bar, then press Return: * *KQL* — `referer : *facebook.com*` * *Label* — `Facebook` -.. Click *Add a filter*, enter the following, then press Return: +. Click *Add a filter*, enter the following in the query bar, then press Return: * *KQL* — `referer : *twitter.com*` * *Label* — `Twitter` -.. Click *Add a filter*, enter the following, then press Return: +. Click *Add a filter*, enter the following in the query bar, then press Return: * *KQL* — `NOT referer : *twitter.com* OR NOT referer: *facebook.com*` * *Label* — `Other` -.. Click *Close*. +. Click *Close*. -Add a geography grouping: +Add the user geography grouping: -. From the *Available fields* list, drag *geo.src* to the workspace. +. From the *Available fields* list, drag *geo.srcdest* to the workspace. -. To change the *Group by* order, drag *Top values of geo.src* so that it appears first. +. To change the *Group by* order, drag *Top values of geo.srcdest* in the layer pane so that appears first. + [role="screenshot"] image::images/lens_end_to_end_7_2.png[Treemap visualization] -. To view only the Facebook and Twitter data, remove the *Other* category. +Remove the documents that do not match the filter criteria: -.. In the layer pane, click *Top values of geo.src*. +. In the layer pane, click *Top values of geo.srcdest*. -.. Open the *Advanced* dropdown, deselect *Group other values as "Other"*, then click *Close*. +. Click *Advanced*, then deselect *Group other values as "Other"*, the click *Close*. ++ +[role="screenshot"] +image::images/lens_treemapMultiLevelChart_7.16.png[Treemap visualization] . Click *Save and return*. -. Add a panel title. +Add a panel title: -.. Open the panel menu, then select *Edit panel title*. +. Open the panel menu, then select *Edit panel title*. -.. In the *Panel title* field, enter `Page views by location and referrer`, then click *Save*. +. In the *Panel title* field, enter `Page views by location and referrer`, then click *Save*. [float] [[arrange-the-lens-panels]] @@ -317,7 +350,7 @@ image::images/lens_end_to_end_7_2.png[Treemap visualization] Resize and move the panels so they all appear on the dashboard without scrolling. -Decrease the size of the following panels, then move them to the first row: +Decrease the size of the following panels, then move the panels to the first row: * *Unique visitors* @@ -325,7 +358,10 @@ Decrease the size of the following panels, then move them to the first row: * *Sum of bytes from large requests* -* *hour_of_day* +* *Website traffic* ++ +[role="screenshot"] +image::images/lens_logsDashboard_7.16.png[Logs dashboard] [discrete] === Save the dashboard diff --git a/docs/user/security/securing-kibana.asciidoc b/docs/user/security/securing-kibana.asciidoc index a4ec2ecadece3..bdb36a6fe117c 100644 --- a/docs/user/security/securing-kibana.asciidoc +++ b/docs/user/security/securing-kibana.asciidoc @@ -108,7 +108,7 @@ TIP: For more information on Basic Authentication and additional methods of auth TIP: You can define as many different roles for your {kib} users as you need. For example, create roles that have `read` and `view_index_metadata` privileges -on specific index patterns. For more information, see +on specific data views. For more information, see {ref}/authorization.html[User authorization]. -- diff --git a/package.json b/package.json index 440a30d36534e..e68654549a4f2 100644 --- a/package.json +++ b/package.json @@ -771,7 +771,6 @@ "oboe": "^2.1.4", "parse-link-header": "^1.0.1", "pbf": "3.2.1", - "pdf-to-img": "^1.1.1", "pirates": "^4.0.1", "pixelmatch": "^5.1.0", "postcss": "^7.0.32", diff --git a/packages/elastic-apm-synthtrace/src/lib/utils/clean_write_targets.ts b/packages/elastic-apm-synthtrace/src/lib/utils/clean_write_targets.ts index 3c514e1097b31..4a2ab281a2849 100644 --- a/packages/elastic-apm-synthtrace/src/lib/utils/clean_write_targets.ts +++ b/packages/elastic-apm-synthtrace/src/lib/utils/clean_write_targets.ts @@ -27,6 +27,7 @@ export async function cleanWriteTargets({ index: targets, allow_no_indices: true, conflicts: 'proceed', + refresh: true, body: { query: { match_all: {}, 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 b5d379d3426e7..4130cd8d138b8 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 @@ -78,18 +78,33 @@ export class FunctionalTestRunner { // replace the function of custom service providers so that they return // promise-like objects which never resolve, essentially disabling them // allowing us to load the test files and populate the mocha suites - const readStubbedProviderSpec = (type: string, providers: any) => + const readStubbedProviderSpec = (type: string, providers: any, skip: string[]) => readProviderSpec(type, providers).map((p) => ({ ...p, - fn: () => ({ - then: () => {}, - }), + fn: skip.includes(p.name) + ? (...args: unknown[]) => { + const result = p.fn(...args); + if ('then' in result) { + throw new Error( + `Provider [${p.name}] returns a promise so it can't loaded during test analysis` + ); + } + + return result; + } + : () => ({ + then: () => {}, + }), })); const providers = new ProviderCollection(this.log, [ ...coreProviders, - ...readStubbedProviderSpec('Service', config.get('services')), - ...readStubbedProviderSpec('PageObject', config.get('pageObjects')), + ...readStubbedProviderSpec( + 'Service', + config.get('services'), + config.get('servicesRequiredForTestAnalysis') + ), + ...readStubbedProviderSpec('PageObject', config.get('pageObjects'), []), ]); const mocha = await setupMocha(this.lifecycle, this.log, config, providers); diff --git a/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts b/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts index 7fae313c68bd3..a9ceaa643a60f 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts @@ -89,6 +89,7 @@ export const schema = Joi.object() }) .default(), + servicesRequiredForTestAnalysis: Joi.array().items(Joi.string()).default([]), services: Joi.object().pattern(ID_PATTERN, Joi.func().required()).default(), pageObjects: Joi.object().pattern(ID_PATTERN, Joi.func().required()).default(), diff --git a/scripts/docs.js b/scripts/docs.js index 6522079c7aca3..f310903b90bac 100644 --- a/scripts/docs.js +++ b/scripts/docs.js @@ -7,4 +7,4 @@ */ require('../src/setup_node_env'); -require('../src/docs/cli'); +require('../src/dev/run_build_docs_cli').runBuildDocsCli(); diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts index 5dc214407e206..c54922ecd67df 100644 --- a/src/core/public/doc_links/doc_links_service.ts +++ b/src/core/public/doc_links/doc_links_service.ts @@ -507,6 +507,9 @@ export class DocLinksService { rubyOverview: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/ruby-api/${DOC_LINK_VERSION}/ruby_client.html`, rustGuide: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/rust-api/${DOC_LINK_VERSION}/index.html`, }, + endpoints: { + troubleshooting: `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/ts-management.html#ts-endpoints`, + }, }, }); } @@ -770,5 +773,8 @@ export interface DocLinksStart { readonly rubyOverview: string; readonly rustGuide: string; }; + readonly endpoints: { + readonly troubleshooting: string; + }; }; } diff --git a/src/core/public/overlays/flyout/flyout_service.tsx b/src/core/public/overlays/flyout/flyout_service.tsx index 6e986cc8ecb48..79047738da4dd 100644 --- a/src/core/public/overlays/flyout/flyout_service.tsx +++ b/src/core/public/overlays/flyout/flyout_service.tsx @@ -8,7 +8,7 @@ /* eslint-disable max-classes-per-file */ -import { EuiFlyout, EuiFlyoutSize } from '@elastic/eui'; +import { EuiFlyout, EuiFlyoutSize, EuiOverlayMaskProps } from '@elastic/eui'; import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { Subject } from 'rxjs'; @@ -86,6 +86,7 @@ export interface OverlayFlyoutOpenOptions { size?: EuiFlyoutSize; maxWidth?: boolean | number | string; hideCloseButton?: boolean; + maskProps?: EuiOverlayMaskProps; /** * EuiFlyout onClose handler. * If provided the consumer is responsible for calling flyout.close() to close the flyout; diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 6c377bd2870ae..83aea9774bb56 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -15,6 +15,7 @@ import { EuiButtonEmptyProps } from '@elastic/eui'; import { EuiConfirmModalProps } from '@elastic/eui'; import { EuiFlyoutSize } from '@elastic/eui'; import { EuiGlobalToastListToast } from '@elastic/eui'; +import { EuiOverlayMaskProps } from '@elastic/eui'; import { History } from 'history'; import { Href } from 'history'; import { IconType } from '@elastic/eui'; @@ -728,6 +729,9 @@ export interface DocLinksStart { readonly rubyOverview: string; readonly rustGuide: string; }; + readonly endpoints: { + readonly troubleshooting: string; + }; }; } @@ -1048,6 +1052,8 @@ export interface OverlayFlyoutOpenOptions { // (undocumented) hideCloseButton?: boolean; // (undocumented) + maskProps?: EuiOverlayMaskProps; + // (undocumented) maxWidth?: boolean | number | string; onClose?: (flyout: OverlayRef) => void; // (undocumented) diff --git a/src/dev/bazel/index.bzl b/src/dev/bazel/index.bzl index 313cc9f06236c..83d6361ff95f7 100644 --- a/src/dev/bazel/index.bzl +++ b/src/dev/bazel/index.bzl @@ -12,6 +12,8 @@ Please do not import from any other files when looking to use a custom rule load("//src/dev/bazel:jsts_transpiler.bzl", _jsts_transpiler = "jsts_transpiler") load("//src/dev/bazel:ts_project.bzl", _ts_project = "ts_project") +load("//src/dev/bazel:pkg_npm.bzl", _pkg_npm = "pkg_npm") jsts_transpiler = _jsts_transpiler +pkg_npm = _pkg_npm ts_project = _ts_project diff --git a/src/dev/bazel/pkg_npm.bzl b/src/dev/bazel/pkg_npm.bzl new file mode 100644 index 0000000000000..263d941d4b435 --- /dev/null +++ b/src/dev/bazel/pkg_npm.bzl @@ -0,0 +1,16 @@ +"Simple wrapper over the general pkg_npm rule from rules_nodejs so we can override some configs" + +load("@build_bazel_rules_nodejs//internal/pkg_npm:pkg_npm.bzl", _pkg_npm = "pkg_npm_macro") + +def pkg_npm(validate = False, **kwargs): + """A macro around the upstream pkg_npm rule. + + Args: + validate: boolean; Whether to check that the attributes match the package.json. Defaults to false + **kwargs: the rest + """ + + _pkg_npm( + validate = validate, + **kwargs + ) diff --git a/src/dev/run_build_docs_cli.ts b/src/dev/run_build_docs_cli.ts new file mode 100644 index 0000000000000..aad524b4437d3 --- /dev/null +++ b/src/dev/run_build_docs_cli.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import Path from 'path'; + +import dedent from 'dedent'; +import { run, REPO_ROOT, createFailError } from '@kbn/dev-utils'; + +const DEFAULT_DOC_REPO_PATH = Path.resolve(REPO_ROOT, '..', 'docs'); + +const rel = (path: string) => Path.relative(process.cwd(), path); + +export function runBuildDocsCli() { + run( + async ({ flags, procRunner }) => { + const docRepoPath = + typeof flags.docrepo === 'string' && flags.docrepo + ? Path.resolve(process.cwd(), flags.docrepo) + : DEFAULT_DOC_REPO_PATH; + + try { + await procRunner.run('build_docs', { + cmd: rel(Path.resolve(docRepoPath, 'build_docs')), + args: [ + ['--doc', rel(Path.resolve(REPO_ROOT, 'docs/index.asciidoc'))], + ['--chunk', '1'], + flags.open ? ['--open'] : [], + ].flat(), + cwd: REPO_ROOT, + wait: true, + }); + } catch (error) { + if (error.code === 'ENOENT') { + throw createFailError(dedent` + Unable to run "build_docs" script from docs repo. + Does it exist at [${rel(docRepoPath)}]? + Do you need to pass --docrepo to specify the correct path or clone it there? + `); + } + + throw error; + } + }, + { + description: 'Build the docs and serve them from a docker container', + flags: { + string: ['docrepo'], + boolean: ['open'], + default: { + docrepo: DEFAULT_DOC_REPO_PATH, + }, + help: ` + --docrepo [path] Path to the doc repo, defaults to ${rel(DEFAULT_DOC_REPO_PATH)} + --open Automatically open the built docs in your default browser after building + `, + }, + } + ); +} diff --git a/src/docs/cli.js b/src/docs/cli.js deleted file mode 100644 index ac17c3908f0ca..0000000000000 --- a/src/docs/cli.js +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { execFileSync } from 'child_process'; -import { Command } from 'commander'; - -import { defaultDocsRepoPath, buildDocsScript, buildDocsArgs } from './docs_repo'; - -const cmd = new Command('node scripts/docs'); -cmd - .option('--docrepo [path]', 'local path to the docs repo', defaultDocsRepoPath()) - .option('--open', 'open the docs in the browser', false) - .parse(process.argv); - -try { - execFileSync(buildDocsScript(cmd), buildDocsArgs(cmd)); -} catch (err) { - if (err.code === 'ENOENT') { - console.error(`elastic/docs repo must be cloned to ${cmd.docrepo}`); - } else { - console.error(err.stack); - } - - process.exit(1); -} diff --git a/src/docs/docs_repo.js b/src/docs/docs_repo.js deleted file mode 100644 index 2d3589c444b34..0000000000000 --- a/src/docs/docs_repo.js +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { resolve } from 'path'; - -const kibanaDir = resolve(__dirname, '..', '..'); - -export function buildDocsScript(cmd) { - return resolve(process.cwd(), cmd.docrepo, 'build_docs'); -} - -export function buildDocsArgs(cmd) { - const docsIndexFile = resolve(kibanaDir, 'docs', 'index.asciidoc'); - let args = ['--doc', docsIndexFile, '--direct_html', '--chunk=1']; - if (cmd.open) { - args = [...args, '--open']; - } - return args; -} - -export function defaultDocsRepoPath() { - return resolve(kibanaDir, '..', 'docs'); -} diff --git a/src/plugins/chart_expressions/expression_metric/.storybook/main.js b/src/plugins/chart_expressions/expression_metric/.storybook/main.js index cb483d5394285..f73918da64596 100644 --- a/src/plugins/chart_expressions/expression_metric/.storybook/main.js +++ b/src/plugins/chart_expressions/expression_metric/.storybook/main.js @@ -12,7 +12,10 @@ import { resolve } from 'path'; const mockConfig = { resolve: { alias: { - '../format_service': resolve(__dirname, '../public/__mocks__/format_service.ts'), + '../../../expression_metric/public/services': resolve( + __dirname, + '../public/__mocks__/services.ts' + ), }, }, }; diff --git a/src/plugins/chart_expressions/expression_metric/common/expression_functions/__snapshots__/metric_vis_function.test.ts.snap b/src/plugins/chart_expressions/expression_metric/common/expression_functions/__snapshots__/metric_vis_function.test.ts.snap index 03055764cc4a4..c502c9efa2beb 100644 --- a/src/plugins/chart_expressions/expression_metric/common/expression_functions/__snapshots__/metric_vis_function.test.ts.snap +++ b/src/plugins/chart_expressions/expression_metric/common/expression_functions/__snapshots__/metric_vis_function.test.ts.snap @@ -6,7 +6,8 @@ Object { Object { "id": "col-0-1", "meta": Object { - "dimensionName": undefined, + "dimensionName": "Metric", + "type": "number", }, "name": "Count", }, @@ -27,31 +28,55 @@ Object { "value": Object { "visConfig": Object { "dimensions": Object { - "metrics": undefined, + "metrics": Array [ + Object { + "accessor": 0, + "format": Object { + "id": "number", + "params": Object {}, + }, + "type": "vis_dimension", + }, + ], }, "metric": Object { - "colorSchema": "Green to Red", - "colorsRange": "{range from=0 to=10000}", - "invertColors": false, "labels": Object { "show": true, }, - "metricColorMode": "\\"None\\"", + "metricColorMode": "None", + "palette": Object { + "colors": Array [ + "rgb(0, 0, 0, 0)", + "rgb(112, 38, 231)", + ], + "gradient": false, + "range": "number", + "rangeMax": 150, + "rangeMin": 0, + "stops": Array [ + 0, + 10000, + ], + }, "percentageMode": false, "style": Object { "bgColor": false, - "bgFill": "\\"#000\\"", - "fontSize": 60, + "css": "", "labelColor": false, - "subText": "\\"\\"", + "spec": Object { + "fontSize": "60px", + }, + "type": "style", }, - "useRanges": false, }, }, "visData": Object { "columns": Array [ Object { "id": "col-0-1", + "meta": Object { + "type": "number", + }, "name": "Count", }, ], diff --git a/src/plugins/chart_expressions/expression_metric/common/expression_functions/metric_vis_function.test.ts b/src/plugins/chart_expressions/expression_metric/common/expression_functions/metric_vis_function.test.ts index 1f90322e703b8..faf2f93e4d188 100644 --- a/src/plugins/chart_expressions/expression_metric/common/expression_functions/metric_vis_function.test.ts +++ b/src/plugins/chart_expressions/expression_metric/common/expression_functions/metric_vis_function.test.ts @@ -13,45 +13,39 @@ import { Datatable } from '../../../../expressions/common/expression_types/specs describe('interpreter/functions#metric', () => { const fn = functionWrapper(metricVisFunction()); - const context = { + const context: Datatable = { type: 'datatable', rows: [{ 'col-0-1': 0 }], - columns: [{ id: 'col-0-1', name: 'Count' }], - } as unknown as Datatable; - const args = { + columns: [{ id: 'col-0-1', name: 'Count', meta: { type: 'number' } }], + }; + const args: MetricArguments = { percentageMode: false, - useRanges: false, - colorSchema: 'Green to Red', - metricColorMode: 'None', - colorsRange: [ - { - from: 0, - to: 10000, + colorMode: 'None', + palette: { + type: 'palette', + name: '', + params: { + colors: ['rgb(0, 0, 0, 0)', 'rgb(112, 38, 231)'], + stops: [0, 10000], + gradient: false, + rangeMin: 0, + rangeMax: 150, + range: 'number', }, - ], - labels: { - show: true, - }, - invertColors: false, - style: { - bgFill: '#000', - bgColor: false, - labelColor: false, - subText: '', - fontSize: 60, }, - font: { spec: { fontSize: 60 } }, - metrics: [ + showLabels: true, + font: { spec: { fontSize: '60px' }, type: 'style', css: '' }, + metric: [ { + type: 'vis_dimension', accessor: 0, format: { id: 'number', + params: {}, }, - params: {}, - aggType: 'count', }, ], - } as unknown as MetricArguments; + }; it('returns an object with the correct structure', () => { const actual = fn(context, args, undefined); diff --git a/src/plugins/chart_expressions/expression_metric/common/expression_functions/metric_vis_function.ts b/src/plugins/chart_expressions/expression_metric/common/expression_functions/metric_vis_function.ts index 31f5b8421b3a6..ac3b4f5cc4576 100644 --- a/src/plugins/chart_expressions/expression_metric/common/expression_functions/metric_vis_function.ts +++ b/src/plugins/chart_expressions/expression_metric/common/expression_functions/metric_vis_function.ts @@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n'; import { visType } from '../types'; import { prepareLogTable, Dimension } from '../../../../visualizations/common/prepare_log_table'; -import { vislibColorMaps, ColorMode } from '../../../../charts/common'; +import { ColorMode } from '../../../../charts/common'; import { MetricVisExpressionFunctionDefinition } from '../types'; import { EXPRESSION_METRIC_NAME } from '../constants'; @@ -29,43 +29,18 @@ export const metricVisFunction = (): MetricVisExpressionFunctionDefinition => ({ defaultMessage: 'Shows metric in percentage mode. Requires colorRange to be set.', }), }, - colorSchema: { - types: ['string'], - default: '"Green to Red"', - options: Object.values(vislibColorMaps).map((value: any) => value.id), - help: i18n.translate('expressionMetricVis.function.colorSchema.help', { - defaultMessage: 'Color schema to use', - }), - }, colorMode: { types: ['string'], - default: '"None"', + default: `"${ColorMode.None}"`, options: [ColorMode.None, ColorMode.Labels, ColorMode.Background], help: i18n.translate('expressionMetricVis.function.colorMode.help', { defaultMessage: 'Which part of metric to color', }), }, - colorRange: { - types: ['range'], - multi: true, - default: '{range from=0 to=10000}', - help: i18n.translate('expressionMetricVis.function.colorRange.help', { - defaultMessage: - 'A range object specifying groups of values to which different colors should be applied.', - }), - }, - useRanges: { - types: ['boolean'], - default: false, - help: i18n.translate('expressionMetricVis.function.useRanges.help', { - defaultMessage: 'Enabled color ranges.', - }), - }, - invertColors: { - types: ['boolean'], - default: false, - help: i18n.translate('expressionMetricVis.function.invertColors.help', { - defaultMessage: 'Inverts the color ranges', + palette: { + types: ['palette'], + help: i18n.translate('expressionMetricVis.function.palette.help', { + defaultMessage: 'Provides colors for the values, based on the bounds.', }), }, showLabels: { @@ -75,29 +50,12 @@ export const metricVisFunction = (): MetricVisExpressionFunctionDefinition => ({ defaultMessage: 'Shows labels under the metric values.', }), }, - bgFill: { - types: ['string'], - default: '"#000"', - aliases: ['backgroundFill', 'bgColor', 'backgroundColor'], - help: i18n.translate('expressionMetricVis.function.bgFill.help', { - defaultMessage: - 'Color as html hex code (#123456), html color (red, blue) or rgba value (rgba(255,255,255,1)).', - }), - }, font: { types: ['style'], help: i18n.translate('expressionMetricVis.function.font.help', { defaultMessage: 'Font settings.', }), - default: '{font size=60}', - }, - subText: { - types: ['string'], - aliases: ['label', 'text', 'description'], - default: '""', - help: i18n.translate('expressionMetricVis.function.subText.help', { - defaultMessage: 'Custom text to show under the metric', - }), + default: `{font size=60 align="center"}`, }, metric: { types: ['vis_dimension'], @@ -115,12 +73,10 @@ export const metricVisFunction = (): MetricVisExpressionFunctionDefinition => ({ }, }, fn(input, args, handlers) { - if (args.percentageMode && (!args.colorRange || args.colorRange.length === 0)) { - throw new Error('colorRange must be provided when using percentageMode'); + if (args.percentageMode && !args.palette?.params) { + throw new Error('Palette must be provided when using percentageMode'); } - const fontSize = Number.parseInt(args.font.spec.fontSize || '', 10); - if (handlers?.inspectorAdapters?.tables) { const argsTable: Dimension[] = [ [ @@ -150,21 +106,16 @@ export const metricVisFunction = (): MetricVisExpressionFunctionDefinition => ({ visType, visConfig: { metric: { + palette: args.palette?.params, percentageMode: args.percentageMode, - useRanges: args.useRanges, - colorSchema: args.colorSchema, metricColorMode: args.colorMode, - colorsRange: args.colorRange, labels: { show: args.showLabels, }, - invertColors: args.invertColors, style: { - bgFill: args.bgFill, bgColor: args.colorMode === ColorMode.Background, labelColor: args.colorMode === ColorMode.Labels, - subText: args.subText, - fontSize, + ...args.font, }, }, dimensions: { diff --git a/src/plugins/chart_expressions/expression_metric/common/types/expression_functions.ts b/src/plugins/chart_expressions/expression_metric/common/types/expression_functions.ts index 5e8b01ec93005..88bc0310a6a04 100644 --- a/src/plugins/chart_expressions/expression_metric/common/types/expression_functions.ts +++ b/src/plugins/chart_expressions/expression_metric/common/types/expression_functions.ts @@ -9,35 +9,29 @@ import { Datatable, ExpressionFunctionDefinition, - Range, ExpressionValueRender, Style, } from '../../../../expressions'; import { ExpressionValueVisDimension } from '../../../../visualizations/common'; -import { ColorSchemas, ColorMode } from '../../../../charts/common'; +import { ColorMode, CustomPaletteState, PaletteOutput } from '../../../../charts/common'; import { VisParams, visType } from './expression_renderers'; import { EXPRESSION_METRIC_NAME } from '../constants'; export interface MetricArguments { percentageMode: boolean; - colorSchema: ColorSchemas; colorMode: ColorMode; - useRanges: boolean; - invertColors: boolean; showLabels: boolean; - bgFill: string; - subText: string; - colorRange: Range[]; + palette?: PaletteOutput; font: Style; metric: ExpressionValueVisDimension[]; - bucket: ExpressionValueVisDimension; + bucket?: ExpressionValueVisDimension; } export type MetricInput = Datatable; export interface MetricVisRenderConfig { visType: typeof visType; - visData: MetricInput; + visData: Datatable; visConfig: Pick; } diff --git a/src/plugins/chart_expressions/expression_metric/common/types/expression_renderers.ts b/src/plugins/chart_expressions/expression_metric/common/types/expression_renderers.ts index 2cc7ce853f8bf..eb7573183894c 100644 --- a/src/plugins/chart_expressions/expression_metric/common/types/expression_renderers.ts +++ b/src/plugins/chart_expressions/expression_metric/common/types/expression_renderers.ts @@ -5,9 +5,15 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { Range } from '../../../../expressions/common'; + import { ExpressionValueVisDimension } from '../../../../visualizations/common'; -import { ColorMode, Labels, Style, ColorSchemas } from '../../../../charts/common'; +import { + ColorMode, + Labels, + CustomPaletteState, + Style as ChartStyle, +} from '../../../../charts/common'; +import { Style } from '../../../../expressions/common'; export const visType = 'metric'; @@ -16,16 +22,14 @@ export interface DimensionsVisParam { bucket?: ExpressionValueVisDimension; } +export type MetricStyle = Style & Pick; export interface MetricVisParam { percentageMode: boolean; percentageFormatPattern?: string; - useRanges: boolean; - colorSchema: ColorSchemas; metricColorMode: ColorMode; - colorsRange: Range[]; + palette?: CustomPaletteState; labels: Labels; - invertColors: boolean; - style: Style; + style: MetricStyle; } export interface VisParams { @@ -42,5 +46,4 @@ export interface MetricOptions { color?: string; bgColor?: string; lightText: boolean; - rowIndex: number; } diff --git a/src/plugins/chart_expressions/expression_metric/public/__mocks__/palette_service.ts b/src/plugins/chart_expressions/expression_metric/public/__mocks__/palette_service.ts new file mode 100644 index 0000000000000..89872b4461be3 --- /dev/null +++ b/src/plugins/chart_expressions/expression_metric/public/__mocks__/palette_service.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { CustomPaletteState } from 'src/plugins/charts/common'; + +export const getPaletteService = () => { + return { + get: (paletteName: string) => ({ + getColorForValue: (value: number, params: CustomPaletteState) => { + const { colors = [], stops = [] } = params ?? {}; + const lessThenValueIndex = stops.findIndex((stop) => value <= stop); + return colors[lessThenValueIndex]; + }, + }), + }; +}; diff --git a/src/plugins/chart_expressions/expression_metric/public/__mocks__/services.ts b/src/plugins/chart_expressions/expression_metric/public/__mocks__/services.ts new file mode 100644 index 0000000000000..c87fa71aa5862 --- /dev/null +++ b/src/plugins/chart_expressions/expression_metric/public/__mocks__/services.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { getFormatService } from './format_service'; +export { getPaletteService } from './palette_service'; diff --git a/src/plugins/chart_expressions/expression_metric/public/__stories__/metric_renderer.stories.tsx b/src/plugins/chart_expressions/expression_metric/public/__stories__/metric_renderer.stories.tsx index b22616af01c91..748ef15a6c9c9 100644 --- a/src/plugins/chart_expressions/expression_metric/public/__stories__/metric_renderer.stories.tsx +++ b/src/plugins/chart_expressions/expression_metric/public/__stories__/metric_renderer.stories.tsx @@ -9,11 +9,31 @@ import React from 'react'; import { storiesOf } from '@storybook/react'; import { ExpressionValueVisDimension } from '../../../../visualizations/common'; -import { DatatableColumn, Range } from '../../../../expressions'; +import { Datatable, DatatableColumn } from '../../../../expressions'; import { Render } from '../../../../presentation_util/public/__stories__'; -import { ColorMode, ColorSchemas } from '../../../../charts/common'; +import { ColorMode, CustomPaletteState } from '../../../../charts/common'; import { metricVisRenderer } from '../expression_renderers'; -import { MetricVisRenderConfig, visType } from '../../common/types'; +import { MetricStyle, MetricVisRenderConfig, visType } from '../../common/types'; + +const palette: CustomPaletteState = { + colors: ['rgb(219 231 38)', 'rgb(112 38 231)', 'rgb(38 124 231)'], + stops: [0, 50, 150], + gradient: false, + rangeMin: 0, + rangeMax: 150, + range: 'number', +}; + +const style: MetricStyle = { + spec: { fontSize: '12px' }, + + /* stylelint-disable */ + type: 'style', + css: '', + bgColor: false, + labelColor: false, + /* stylelint-enable */ +}; const config: MetricVisRenderConfig = { visType, @@ -35,20 +55,10 @@ const config: MetricVisRenderConfig = { }, visConfig: { metric: { - percentageMode: false, - useRanges: false, - colorSchema: ColorSchemas.GreenToRed, metricColorMode: ColorMode.None, - colorsRange: [], labels: { show: true }, - invertColors: false, - style: { - bgColor: false, - bgFill: '#000', - fontSize: 60, - labelColor: false, - subText: '', - }, + percentageMode: false, + style, }, dimensions: { metrics: [ @@ -102,11 +112,6 @@ const dataWithBuckets = [ { 'col-0-1': 56, 'col-0-2': 52, 'col-0-3': 'Wednesday' }, ]; -const colorsRange: Range[] = [ - { type: 'range', from: 0, to: 50 }, - { type: 'range', from: 51, to: 150 }, -]; - const containerSize = { width: '700px', height: '700px', @@ -141,7 +146,10 @@ storiesOf('renderers/visMetric', module) ...config.visConfig, metric: { ...config.visConfig.metric, - style: { ...config.visConfig.metric.style, fontSize: 120 }, + style: { + ...config.visConfig.metric.style, + spec: { ...config.visConfig.metric.style.spec, fontSize: '120px' }, + }, }, }, }} @@ -159,7 +167,7 @@ storiesOf('renderers/visMetric', module) ...config.visConfig, metric: { ...config.visConfig.metric, - colorsRange, + palette, metricColorMode: ColorMode.Background, style: { ...config.visConfig.metric.style, @@ -182,7 +190,7 @@ storiesOf('renderers/visMetric', module) ...config.visConfig, metric: { ...config.visConfig.metric, - colorsRange, + palette, metricColorMode: ColorMode.Labels, style: { ...config.visConfig.metric.style, @@ -205,13 +213,12 @@ storiesOf('renderers/visMetric', module) ...config.visConfig, metric: { ...config.visConfig.metric, - colorsRange, + palette, metricColorMode: ColorMode.Labels, style: { ...config.visConfig.metric.style, labelColor: true, }, - invertColors: true, }, }, }} @@ -226,8 +233,8 @@ storiesOf('renderers/visMetric', module) config={{ ...config, visData: { - ...config.visData, - columns: [...config.visData.columns, dayColumn], + ...(config.visData as Datatable), + columns: [...(config.visData as Datatable).columns, dayColumn], rows: dataWithBuckets, }, visConfig: { @@ -243,7 +250,7 @@ storiesOf('renderers/visMetric', module) return ( ); diff --git a/src/plugins/chart_expressions/expression_metric/public/components/__snapshots__/metric_component.test.tsx.snap b/src/plugins/chart_expressions/expression_metric/public/components/__snapshots__/metric_component.test.tsx.snap index f07fdfa682d87..5f856f3154d58 100644 --- a/src/plugins/chart_expressions/expression_metric/public/components/__snapshots__/metric_component.test.tsx.snap +++ b/src/plugins/chart_expressions/expression_metric/public/components/__snapshots__/metric_component.test.tsx.snap @@ -15,6 +15,15 @@ Array [ } } showLabel={true} + style={ + Object { + "bgColor": false, + "css": "", + "labelColor": false, + "spec": Object {}, + "type": "style", + } + } />, , ] `; @@ -47,5 +65,14 @@ exports[`MetricVisComponent should render correct structure for single metric 1` } } showLabel={true} + style={ + Object { + "bgColor": false, + "css": "", + "labelColor": false, + "spec": Object {}, + "type": "style", + } + } /> `; diff --git a/src/plugins/chart_expressions/expression_metric/public/components/metric.scss b/src/plugins/chart_expressions/expression_metric/public/components/metric.scss index 5665ba8e8d099..24c5c05129882 100644 --- a/src/plugins/chart_expressions/expression_metric/public/components/metric.scss +++ b/src/plugins/chart_expressions/expression_metric/public/components/metric.scss @@ -6,6 +6,7 @@ // mtrChart__legend-isLoading .mtrVis { + height: 100%; width: 100%; display: flex; flex-direction: row; diff --git a/src/plugins/chart_expressions/expression_metric/public/components/metric_component.test.tsx b/src/plugins/chart_expressions/expression_metric/public/components/metric_component.test.tsx index ec3b9aee8583c..033cdd629b8eb 100644 --- a/src/plugins/chart_expressions/expression_metric/public/components/metric_component.test.tsx +++ b/src/plugins/chart_expressions/expression_metric/public/components/metric_component.test.tsx @@ -8,49 +8,64 @@ import React from 'react'; import { shallow } from 'enzyme'; - +import { Datatable } from '../../../../expressions/common'; import MetricVisComponent, { MetricVisComponentProps } from './metric_component'; -jest.mock('../format_service', () => ({ - getFormatService: () => ({ - deserialize: () => { - return { - convert: (x: unknown) => x, - }; - }, - }), +jest.mock('../../../expression_metric/public/services', () => ({ + getFormatService: () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const { getFormatService } = require('../__mocks__/services'); + return getFormatService(); + }, + getPaletteService: () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const { getPaletteService } = require('../__mocks__/services'); + return getPaletteService(); + }, })); type Props = MetricVisComponentProps; -const baseVisData = { - columns: [{ id: 'col-0', name: 'Count' }], +const visData: Datatable = { + type: 'datatable', + columns: [{ id: 'col-0', name: 'Count', meta: { type: 'number' } }], rows: [{ 'col-0': 4301021 }], -} as any; +}; describe('MetricVisComponent', function () { - const visParams = { - type: 'metric', - addTooltip: false, - addLegend: false, + const visParams: Props['visParams'] = { metric: { - colorSchema: 'Green to Red', - colorsRange: [{ from: 0, to: 1000 }], - style: {}, + metricColorMode: 'None', + percentageMode: false, + palette: { + colors: ['rgb(0, 0, 0, 0)', 'rgb(112, 38, 231)'], + stops: [0, 10000], + gradient: false, + rangeMin: 0, + rangeMax: 1000, + range: 'number', + }, + style: { + type: 'style', + spec: {}, + css: '', + bgColor: false, + labelColor: false, + }, labels: { show: true, }, }, dimensions: { - metrics: [{ accessor: 0 } as any], + metrics: [{ accessor: 0, type: 'vis_dimension', format: { params: {}, id: 'number' } }], bucket: undefined, }, }; const getComponent = (propOverrides: Partial = {} as Partial) => { const props: Props = { - visParams: visParams as any, - visData: baseVisData, + visParams, + visData, renderComplete: jest.fn(), fireEvent: jest.fn(), ...propOverrides, @@ -70,9 +85,10 @@ describe('MetricVisComponent', function () { it('should render correct structure for multi-value metrics', function () { const component = getComponent({ visData: { + type: 'datatable', columns: [ - { id: 'col-0', name: '1st percentile of bytes' }, - { id: 'col-1', name: '99th percentile of bytes' }, + { id: 'col-0', name: '1st percentile of bytes', meta: { type: 'number' } }, + { id: 'col-1', name: '99th percentile of bytes', meta: { type: 'number' } }, ], rows: [{ 'col-0': 182, 'col-1': 445842.4634666484 }], }, @@ -80,10 +96,13 @@ describe('MetricVisComponent', function () { ...visParams, dimensions: { ...visParams.dimensions, - metrics: [{ accessor: 0 }, { accessor: 1 }], + metrics: [ + { accessor: 0, type: 'vis_dimension', format: { id: 'number', params: {} } }, + { accessor: 1, type: 'vis_dimension', format: { id: 'number', params: {} } }, + ], }, }, - } as any); + }); expect(component).toMatchSnapshot(); }); diff --git a/src/plugins/chart_expressions/expression_metric/public/components/metric_component.tsx b/src/plugins/chart_expressions/expression_metric/public/components/metric_component.tsx index 4efdefc7d28ee..245fdf0a37170 100644 --- a/src/plugins/chart_expressions/expression_metric/public/components/metric_component.tsx +++ b/src/plugins/chart_expressions/expression_metric/public/components/metric_component.tsx @@ -6,161 +6,92 @@ * Side Public License, v 1. */ -import { last, findIndex, isNaN } from 'lodash'; import React, { Component } from 'react'; -import { isColorDark } from '@elastic/eui'; import { MetricVisValue } from './metric_value'; -import { MetricInput, VisParams, MetricOptions } from '../../common/types'; -import type { FieldFormatsContentType, IFieldFormat } from '../../../../field_formats/common'; +import { VisParams, MetricOptions } from '../../common/types'; +import type { IFieldFormat } from '../../../../field_formats/common'; import { Datatable } from '../../../../expressions/public'; -import { getHeatmapColors } from '../../../../charts/public'; -import { getFormatService } from '../format_service'; +import { CustomPaletteState } from '../../../../charts/public'; +import { getFormatService, getPaletteService } from '../../../expression_metric/public/services'; import { ExpressionValueVisDimension } from '../../../../visualizations/public'; +import { formatValue, shouldApplyColor } from '../utils'; +import { getColumnByAccessor } from '../utils/accessor'; +import { needsLightText } from '../utils/palette'; import './metric.scss'; export interface MetricVisComponentProps { visParams: Pick; - visData: MetricInput; + visData: Datatable; fireEvent: (event: any) => void; renderComplete: () => void; } class MetricVisComponent extends Component { - private getLabels() { - const config = this.props.visParams.metric; - const isPercentageMode = config.percentageMode; - const colorsRange = config.colorsRange; - const max = last(colorsRange)?.to ?? 1; - const labels: string[] = []; - - colorsRange.forEach((range: any) => { - const from = isPercentageMode ? Math.round((100 * range.from) / max) : range.from; - const to = isPercentageMode ? Math.round((100 * range.to) / max) : range.to; - labels.push(`${from} - ${to}`); + private getColor(value: number, paletteParams: CustomPaletteState) { + return getPaletteService().get('custom')?.getColorForValue?.(value, paletteParams, { + min: paletteParams.rangeMin, + max: paletteParams.rangeMax, }); - return labels; - } - - private getColors() { - const config = this.props.visParams.metric; - const invertColors = config.invertColors; - const colorSchema = config.colorSchema; - const colorsRange = config.colorsRange; - const labels = this.getLabels(); - const colors: any = {}; - for (let i = 0; i < labels.length; i += 1) { - const divider = Math.max(colorsRange.length - 1, 1); - const val = invertColors ? 1 - i / divider : i / divider; - colors[labels[i]] = getHeatmapColors(val, colorSchema); - } - return colors; - } - - private getBucket(val: number) { - const config = this.props.visParams.metric; - let bucket = findIndex(config.colorsRange, (range: any) => { - return range.from <= val && range.to > val; - }); - - if (bucket === -1) { - if (config.colorsRange?.[0] && val < config.colorsRange?.[0].from) bucket = 0; - else bucket = config.colorsRange.length - 1; - } - - return bucket; - } - - private getColor(val: number, labels: string[], colors: { [label: string]: string }) { - const bucket = this.getBucket(val); - const label = labels[bucket]; - return colors[label]; - } - - private needsLightText(bgColor: string) { - const colors = /rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/.exec(bgColor); - if (!colors) { - return false; - } - - const [red, green, blue] = colors.slice(1).map((c) => parseInt(c, 10)); - return isColorDark(red, green, blue); - } - - private getFormattedValue = ( - fieldFormatter: IFieldFormat, - value: any, - format: FieldFormatsContentType = 'text' - ) => { - if (isNaN(value)) return '-'; - return fieldFormatter.convert(value, format); - }; - - private getColumn( - accessor: ExpressionValueVisDimension['accessor'], - columns: Datatable['columns'] = [] - ) { - if (typeof accessor === 'number') { - return columns[accessor]; - } - return columns.filter(({ id }) => accessor.id === id)[0]; } private processTableGroups(table: Datatable) { const { metric: metricConfig, dimensions } = this.props.visParams; - const { percentageMode: isPercentageMode, colorsRange, style } = metricConfig; - const min = colorsRange?.[0]?.from; - const max = last(colorsRange)?.to; - const colors = this.getColors(); - const labels = this.getLabels(); - const metrics: MetricOptions[] = []; + const { percentageMode: isPercentageMode, style, palette } = metricConfig; + const { stops = [] } = palette ?? {}; + const min = stops[0]; + const max = stops[stops.length - 1]; let bucketColumnId: string; let bucketFormatter: IFieldFormat; if (dimensions.bucket) { - bucketColumnId = this.getColumn(dimensions.bucket.accessor, table.columns).id; + bucketColumnId = getColumnByAccessor(dimensions.bucket.accessor, table.columns).id; bucketFormatter = getFormatService().deserialize(dimensions.bucket.format); } - dimensions.metrics.forEach((metric: ExpressionValueVisDimension) => { - const column = this.getColumn(metric.accessor, table?.columns); - const formatter = getFormatService().deserialize(metric.format); - table.rows.forEach((row, rowIndex) => { - let title = column.name; - let value: number = row[column.id]; - const color = this.getColor(value, labels, colors); - - if (isPercentageMode && colorsRange?.length && max !== undefined && min !== undefined) { - value = (value - min) / (max - min); - } - const formattedValue = this.getFormattedValue(formatter, value, 'html'); - if (bucketColumnId) { - const bucketValue = this.getFormattedValue(bucketFormatter, row[bucketColumnId]); - title = `${bucketValue} - ${title}`; - } - - const shouldColor = colorsRange && colorsRange.length > 1; - - metrics.push({ - label: title, - value: formattedValue, - color: shouldColor && style.labelColor ? color : undefined, - bgColor: shouldColor && style.bgColor ? color : undefined, - lightText: shouldColor && style.bgColor && this.needsLightText(color), - rowIndex, + return dimensions.metrics.reduce( + (acc: MetricOptions[], metric: ExpressionValueVisDimension) => { + const column = getColumnByAccessor(metric.accessor, table?.columns); + const formatter = getFormatService().deserialize(metric.format); + const metrics = table.rows.map((row, rowIndex) => { + let title = column.name; + let value: number = row[column.id]; + const color = palette ? this.getColor(value, palette) : undefined; + + if (isPercentageMode && stops.length) { + value = (value - min) / (max - min); + } + + const formattedValue = formatValue(value, formatter, 'html'); + if (bucketColumnId) { + const bucketValue = formatValue(row[bucketColumnId], bucketFormatter); + title = `${bucketValue} - ${title}`; + } + + const shouldBrush = stops.length > 1 && shouldApplyColor(color ?? ''); + return { + label: title, + value: formattedValue, + color: shouldBrush && (style.labelColor ?? false) ? color : undefined, + bgColor: shouldBrush && (style.bgColor ?? false) ? color : undefined, + lightText: shouldBrush && (style.bgColor ?? false) && needsLightText(color), + rowIndex, + }; }); - }); - }); - return metrics; + return [...acc, ...metrics]; + }, + [] + ); } - private filterBucket = (metric: MetricOptions) => { - const dimensions = this.props.visParams.dimensions; + private filterBucket = (row: number) => { + const { dimensions } = this.props.visParams; if (!dimensions.bucket) { return; } + const table = this.props.visData; this.props.fireEvent({ name: 'filterBucket', @@ -169,7 +100,7 @@ class MetricVisComponent extends Component { { table, column: dimensions.bucket.accessor, - row: metric.rowIndex, + row, }, ], }, @@ -181,8 +112,10 @@ class MetricVisComponent extends Component { this.filterBucket(index) : undefined + } showLabel={this.props.visParams.metric.labels.show} /> ); diff --git a/src/plugins/chart_expressions/expression_metric/public/components/metric_value.test.tsx b/src/plugins/chart_expressions/expression_metric/public/components/metric_value.test.tsx index db145f85a0d4a..9a9e0eef5df97 100644 --- a/src/plugins/chart_expressions/expression_metric/public/components/metric_value.test.tsx +++ b/src/plugins/chart_expressions/expression_metric/public/components/metric_value.test.tsx @@ -10,33 +10,44 @@ import React from 'react'; import { shallow } from 'enzyme'; import { MetricVisValue } from './metric_value'; +import { MetricOptions, MetricStyle } from '../../common/types'; -const baseMetric = { label: 'Foo', value: 'foo' } as any; +const baseMetric: MetricOptions = { label: 'Foo', value: 'foo', lightText: false }; +const font: MetricStyle = { + spec: { fontSize: '12px' }, + + /* stylelint-disable */ + type: 'style', + css: '', + bgColor: false, + labelColor: false, + /* stylelint-enable */ +}; describe('MetricVisValue', () => { it('should be wrapped in button if having a click listener', () => { const component = shallow( - {}} /> + {}} /> ); expect(component.find('button').exists()).toBe(true); }); it('should not be wrapped in button without having a click listener', () => { - const component = shallow(); + const component = shallow(); expect(component.find('button').exists()).toBe(false); }); it('should add -isfilterable class if onFilter is provided', () => { const onFilter = jest.fn(); const component = shallow( - + ); component.simulate('click'); expect(component.find('.mtrVis__container-isfilterable')).toHaveLength(1); }); it('should not add -isfilterable class if onFilter is not provided', () => { - const component = shallow(); + const component = shallow(); component.simulate('click'); expect(component.find('.mtrVis__container-isfilterable')).toHaveLength(0); }); @@ -44,9 +55,9 @@ describe('MetricVisValue', () => { it('should call onFilter callback if provided', () => { const onFilter = jest.fn(); const component = shallow( - + ); component.simulate('click'); - expect(onFilter).toHaveBeenCalledWith(baseMetric); + expect(onFilter).toHaveBeenCalled(); }); }); diff --git a/src/plugins/chart_expressions/expression_metric/public/components/metric_value.tsx b/src/plugins/chart_expressions/expression_metric/public/components/metric_value.tsx index 9554c7ab13616..54662ee647b6a 100644 --- a/src/plugins/chart_expressions/expression_metric/public/components/metric_value.tsx +++ b/src/plugins/chart_expressions/expression_metric/public/components/metric_value.tsx @@ -6,19 +6,18 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { CSSProperties } from 'react'; import classNames from 'classnames'; - -import type { MetricOptions } from '../../common/types'; +import type { MetricOptions, MetricStyle } from '../../common/types'; interface MetricVisValueProps { metric: MetricOptions; - fontSize: number; - onFilter?: (metric: MetricOptions) => void; + onFilter?: () => void; showLabel?: boolean; + style: MetricStyle; } -export const MetricVisValue = ({ fontSize, metric, onFilter, showLabel }: MetricVisValueProps) => { +export const MetricVisValue = ({ style, metric, onFilter, showLabel }: MetricVisValueProps) => { const containerClassName = classNames('mtrVis__container', { // eslint-disable-next-line @typescript-eslint/naming-convention 'mtrVis__container--light': metric.lightText, @@ -31,8 +30,8 @@ export const MetricVisValue = ({ fontSize, metric, onFilter, showLabel }: Metric
onFilter(metric)}> + ); diff --git a/src/plugins/chart_expressions/expression_metric/public/plugin.ts b/src/plugins/chart_expressions/expression_metric/public/plugin.ts index 3ac338380a398..6053cba597b4b 100644 --- a/src/plugins/chart_expressions/expression_metric/public/plugin.ts +++ b/src/plugins/chart_expressions/expression_metric/public/plugin.ts @@ -6,16 +6,18 @@ * Side Public License, v 1. */ +import { ChartsPluginSetup } from '../../../charts/public'; import { CoreSetup, CoreStart, Plugin } from '../../../../core/public'; import { Plugin as ExpressionsPublicPlugin } from '../../../expressions/public'; import { metricVisFunction } from '../common'; -import { setFormatService } from './format_service'; +import { setFormatService, setPaletteService } from './services'; import { metricVisRenderer } from './expression_renderers'; import { FieldFormatsStart } from '../../../field_formats/public'; /** @internal */ export interface ExpressionMetricPluginSetup { expressions: ReturnType; + charts: ChartsPluginSetup; } /** @internal */ @@ -25,9 +27,12 @@ export interface ExpressionMetricPluginStart { /** @internal */ export class ExpressionMetricPlugin implements Plugin { - public setup(core: CoreSetup, { expressions }: ExpressionMetricPluginSetup) { + public setup(core: CoreSetup, { expressions, charts }: ExpressionMetricPluginSetup) { expressions.registerFunction(metricVisFunction); expressions.registerRenderer(metricVisRenderer); + charts.palettes.getPalettes().then((palettes) => { + setPaletteService(palettes); + }); } public start(core: CoreStart, { fieldFormats }: ExpressionMetricPluginStart) { diff --git a/src/plugins/chart_expressions/expression_metric/public/services/format_service.ts b/src/plugins/chart_expressions/expression_metric/public/services/format_service.ts new file mode 100644 index 0000000000000..73b66341c4d9a --- /dev/null +++ b/src/plugins/chart_expressions/expression_metric/public/services/format_service.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { createGetterSetter } from '../../../../kibana_utils/public'; +import { FieldFormatsStart } from '../../../../field_formats/public'; + +export const [getFormatService, setFormatService] = + createGetterSetter('fieldFormats'); diff --git a/src/plugins/chart_expressions/expression_metric/public/services/index.ts b/src/plugins/chart_expressions/expression_metric/public/services/index.ts new file mode 100644 index 0000000000000..0b445d9c10b72 --- /dev/null +++ b/src/plugins/chart_expressions/expression_metric/public/services/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { getFormatService, setFormatService } from './format_service'; +export { getPaletteService, setPaletteService } from './palette_service'; diff --git a/src/plugins/chart_expressions/expression_metric/public/services/palette_service.ts b/src/plugins/chart_expressions/expression_metric/public/services/palette_service.ts new file mode 100644 index 0000000000000..cfcf2a818c5bc --- /dev/null +++ b/src/plugins/chart_expressions/expression_metric/public/services/palette_service.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { createGetterSetter } from '../../../../kibana_utils/public'; +import { PaletteRegistry } from '../../../../charts/public'; + +export const [getPaletteService, setPaletteService] = + createGetterSetter('palette'); diff --git a/src/plugins/chart_expressions/expression_metric/public/utils/accessor.ts b/src/plugins/chart_expressions/expression_metric/public/utils/accessor.ts new file mode 100644 index 0000000000000..679a1ca01affb --- /dev/null +++ b/src/plugins/chart_expressions/expression_metric/public/utils/accessor.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Datatable } from '../../../../expressions'; +import { ExpressionValueVisDimension } from '../../../../visualizations/common'; + +export const getColumnByAccessor = ( + accessor: ExpressionValueVisDimension['accessor'], + columns: Datatable['columns'] = [] +) => { + if (typeof accessor === 'number') { + return columns[accessor]; + } + return columns.filter(({ id }) => accessor.id === id)[0]; +}; diff --git a/src/plugins/chart_expressions/expression_metric/public/utils/format.ts b/src/plugins/chart_expressions/expression_metric/public/utils/format.ts new file mode 100644 index 0000000000000..0339baec9e904 --- /dev/null +++ b/src/plugins/chart_expressions/expression_metric/public/utils/format.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { FieldFormatsContentType, IFieldFormat } from '../../../../field_formats/common'; + +export const formatValue = ( + value: number | string, + fieldFormatter: IFieldFormat, + format: FieldFormatsContentType = 'text' +) => { + if (typeof value === 'number' && isNaN(value)) { + return '-'; + } + + return fieldFormatter.convert(value, format); +}; diff --git a/src/plugins/chart_expressions/expression_metric/public/utils/index.ts b/src/plugins/chart_expressions/expression_metric/public/utils/index.ts new file mode 100644 index 0000000000000..66c305a14c460 --- /dev/null +++ b/src/plugins/chart_expressions/expression_metric/public/utils/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 + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +export { parseRgbString, shouldApplyColor, needsLightText } from './palette'; +export { formatValue } from './format'; diff --git a/src/plugins/chart_expressions/expression_metric/public/utils/palette.ts b/src/plugins/chart_expressions/expression_metric/public/utils/palette.ts new file mode 100644 index 0000000000000..7f588aa552385 --- /dev/null +++ b/src/plugins/chart_expressions/expression_metric/public/utils/palette.ts @@ -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 + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { isColorDark } from '@elastic/eui'; + +export const parseRgbString = (rgb: string) => { + const groups = rgb.match(/rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*?(,\s*(\d+)\s*)?\)/) ?? []; + if (!groups) { + return null; + } + + const red = parseFloat(groups[1]); + const green = parseFloat(groups[2]); + const blue = parseFloat(groups[3]); + const opacity = groups[5] ? parseFloat(groups[5]) : undefined; + + return { red, green, blue, opacity }; +}; + +export const shouldApplyColor = (color: string) => { + const rgb = parseRgbString(color); + const { opacity } = rgb ?? {}; + + // if opacity === 0, it means there is no color to apply to the metric + return !rgb || (rgb && opacity !== 0); +}; + +export const needsLightText = (bgColor: string = '') => { + const rgb = parseRgbString(bgColor); + if (!rgb) { + return false; + } + + const { red, green, blue, opacity } = rgb; + return isColorDark(red, green, blue) && opacity !== 0; +}; diff --git a/src/plugins/charts/common/palette.ts b/src/plugins/charts/common/palette.ts index 1faeb4df7788e..8cd449fe99f99 100644 --- a/src/plugins/charts/common/palette.ts +++ b/src/plugins/charts/common/palette.ts @@ -8,6 +8,7 @@ import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common'; import { i18n } from '@kbn/i18n'; +import { last } from 'lodash'; import { paletteIds } from './constants'; export interface CustomPaletteArguments { @@ -141,21 +142,24 @@ export function palette(): ExpressionFunctionDefinition< }, }, fn: (input, args) => { - const { - color, - continuity, - reverse, - gradient, - stop, - range, - rangeMin = 0, - rangeMax = 100, - } = args; + const { color, continuity, reverse, gradient, stop, range, rangeMin, rangeMax } = args; const colors = ([] as string[]).concat(color || defaultCustomColors); const stops = ([] as number[]).concat(stop || []); if (stops.length > 0 && colors.length !== stops.length) { throw Error('When stop is used, each color must have an associated stop value.'); } + + // If the user has defined stops, choose rangeMin/Max, provided by user or range, + // taken from first/last element of ranges or default range (0 or 100). + const calculateRange = ( + userRange: number | undefined, + stopsRange: number | undefined, + defaultRange: number + ) => userRange ?? stopsRange ?? defaultRange; + + const rangeMinDefault = 0; + const rangeMaxDefault = 100; + return { type: 'palette', name: 'custom', @@ -165,8 +169,8 @@ export function palette(): ExpressionFunctionDefinition< range: range ?? 'percent', gradient, continuity, - rangeMin, - rangeMax, + rangeMin: calculateRange(rangeMin, stops[0], rangeMinDefault), + rangeMax: calculateRange(rangeMax, last(stops), rangeMaxDefault), }, }; }, diff --git a/src/plugins/dashboard/public/application/listing/__snapshots__/dashboard_listing.test.tsx.snap b/src/plugins/dashboard/public/application/listing/__snapshots__/dashboard_listing.test.tsx.snap index 2e37dc61fe851..2f383adb3f5c3 100644 --- a/src/plugins/dashboard/public/application/listing/__snapshots__/dashboard_listing.test.tsx.snap +++ b/src/plugins/dashboard/public/application/listing/__snapshots__/dashboard_listing.test.tsx.snap @@ -34,13 +34,13 @@ exports[`after fetch When given a title that matches multiple dashboards, filter iconType="plusInCircle" onClick={[Function]} > - Create new dashboard + Create a dashboard } body={

- You can combine data views from any Kibana app into one dashboard and see everything in one place. + Analyze all of your Elastic data in one place by creating a dashboard and adding visualizations.

- Install some sample data + Add some sample data , } } @@ -146,13 +146,13 @@ exports[`after fetch initialFilter 1`] = ` iconType="plusInCircle" onClick={[Function]} > - Create new dashboard + Create a dashboard } body={

- You can combine data views from any Kibana app into one dashboard and see everything in one place. + Analyze all of your Elastic data in one place by creating a dashboard and adding visualizations.

- Install some sample data + Add some sample data , } } @@ -257,13 +257,13 @@ exports[`after fetch renders all table rows 1`] = ` iconType="plusInCircle" onClick={[Function]} > - Create new dashboard + Create a dashboard } body={

- You can combine data views from any Kibana app into one dashboard and see everything in one place. + Analyze all of your Elastic data in one place by creating a dashboard and adding visualizations.

- Install some sample data + Add some sample data , } } @@ -368,13 +368,13 @@ exports[`after fetch renders call to action when no dashboards exist 1`] = ` iconType="plusInCircle" onClick={[Function]} > - Create new dashboard + Create a dashboard } body={

- You can combine data views from any Kibana app into one dashboard and see everything in one place. + Analyze all of your Elastic data in one place by creating a dashboard and adding visualizations.

- Install some sample data + Add some sample data , } } @@ -446,6 +446,128 @@ exports[`after fetch renders call to action when no dashboards exist 1`] = ` `; +exports[`after fetch renders call to action with continue when no dashboards exist but one is in progress 1`] = ` + + + + + Discard changes + + + + + Continue editing + + + + } + body={ + +

+ Analyze all of your Elastic data in one place by creating a dashboard and adding visualizations. +

+
+ } + iconType="dashboardApp" + title={ +

+ Dashboard in progress +

+ } + /> + } + entityName="dashboard" + entityNamePlural="dashboards" + findItems={[Function]} + headingId="dashboardListingHeading" + initialFilter="" + initialPageSize={20} + listingLimit={100} + rowHeader="title" + searchFilters={Array []} + tableCaption="Dashboards" + tableColumns={ + Array [ + Object { + "field": "title", + "name": "Title", + "render": [Function], + "sortable": true, + }, + Object { + "field": "description", + "name": "Description", + "render": [Function], + "sortable": true, + }, + ] + } + tableListTitle="Dashboards" + toastNotifications={ + Object { + "add": [MockFunction], + "addDanger": [MockFunction], + "addError": [MockFunction], + "addInfo": [MockFunction], + "addSuccess": [MockFunction], + "addWarning": [MockFunction], + "get$": [MockFunction], + "remove": [MockFunction], + } + } + /> + +`; + exports[`after fetch renders warning when listingLimit is exceeded 1`] = ` - Create new dashboard + Create a dashboard } body={

- You can combine data views from any Kibana app into one dashboard and see everything in one place. + Analyze all of your Elastic data in one place by creating a dashboard and adding visualizations.

- Install some sample data + Add some sample data , } } diff --git a/src/plugins/dashboard/public/application/listing/dashboard_listing.test.tsx b/src/plugins/dashboard/public/application/listing/dashboard_listing.test.tsx index 37ee0ec13d7c9..ff34a63bdce19 100644 --- a/src/plugins/dashboard/public/application/listing/dashboard_listing.test.tsx +++ b/src/plugins/dashboard/public/application/listing/dashboard_listing.test.tsx @@ -16,6 +16,7 @@ import { KibanaContextProvider } from '../../services/kibana_react'; import { createKbnUrlStateStorage } from '../../services/kibana_utils'; import { DashboardListing, DashboardListingProps } from './dashboard_listing'; import { makeDefaultServices } from '../test_helpers'; +import { DASHBOARD_PANELS_UNSAVED_ID } from '../lib/dashboard_session_storage'; function makeDefaultProps(): DashboardListingProps { return { @@ -72,6 +73,25 @@ describe('after fetch', () => { expect(component).toMatchSnapshot(); }); + test('renders call to action with continue when no dashboards exist but one is in progress', async () => { + const services = makeDefaultServices(); + services.savedDashboards.find = () => { + return Promise.resolve({ + total: 0, + hits: [], + }); + }; + services.dashboardSessionStorage.getDashboardIdsWithUnsavedChanges = () => [ + DASHBOARD_PANELS_UNSAVED_ID, + ]; + const { component } = mountWith({ services }); + // Ensure all promises resolve + await new Promise((resolve) => process.nextTick(resolve)); + // Ensure the state changes are reflected + component.update(); + expect(component).toMatchSnapshot(); + }); + test('initialFilter', async () => { const props = makeDefaultProps(); props.initialFilter = 'testFilter'; diff --git a/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx b/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx index 827e5abf2bd6a..8b99b5c51598a 100644 --- a/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx +++ b/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx @@ -7,7 +7,15 @@ */ import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiLink, EuiButton, EuiEmptyPrompt, EuiBasicTableColumn } from '@elastic/eui'; +import { + EuiLink, + EuiButton, + EuiEmptyPrompt, + EuiBasicTableColumn, + EuiFlexGroup, + EuiFlexItem, + EuiButtonEmpty, +} from '@elastic/eui'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { attemptLoadDashboardByTitle } from '../lib'; import { DashboardAppServices, DashboardRedirect } from '../../types'; @@ -15,6 +23,8 @@ import { getDashboardBreadcrumb, dashboardListingTable, noItemsStrings, + dashboardUnsavedListingStrings, + getNewDashboardTitle, } from '../../dashboard_strings'; import { ApplicationStart, SavedObjectsFindOptionsReference } from '../../../../../core/public'; import { syncQueryStateWithUrl } from '../../services/data'; @@ -22,8 +32,9 @@ import { IKbnUrlStateStorage } from '../../services/kibana_utils'; import { TableListView, useKibana } from '../../services/kibana_react'; import { SavedObjectsTaggingApi } from '../../services/saved_objects_tagging_oss'; import { DashboardUnsavedListing } from './dashboard_unsaved_listing'; -import { confirmCreateWithUnsaved } from './confirm_overlays'; +import { confirmCreateWithUnsaved, confirmDiscardUnsavedChanges } from './confirm_overlays'; import { getDashboardListItemLink } from './get_dashboard_list_item_link'; +import { DASHBOARD_PANELS_UNSAVED_ID } from '../lib/dashboard_session_storage'; export interface DashboardListingProps { kbnUrlStateStorage: IKbnUrlStateStorage; @@ -117,10 +128,109 @@ export const DashboardListing = ({ } }, [dashboardSessionStorage, redirectTo, core.overlays]); - const emptyPrompt = useMemo( - () => getNoItemsMessage(showWriteControls, core.application, createItem), - [createItem, core.application, showWriteControls] - ); + const emptyPrompt = useMemo(() => { + if (!showWriteControls) { + return ( + {noItemsStrings.getReadonlyTitle()}} + body={

{noItemsStrings.getReadonlyBody()}

} + /> + ); + } + + const isEditingFirstDashboard = unsavedDashboardIds.length === 1; + + const emptyAction = isEditingFirstDashboard ? ( + + + + confirmDiscardUnsavedChanges(core.overlays, () => { + dashboardSessionStorage.clearState(DASHBOARD_PANELS_UNSAVED_ID); + setUnsavedDashboardIds(dashboardSessionStorage.getDashboardIdsWithUnsavedChanges()); + }) + } + data-test-subj="discardDashboardPromptButton" + aria-label={dashboardUnsavedListingStrings.getDiscardAriaLabel(getNewDashboardTitle())} + > + {dashboardUnsavedListingStrings.getDiscardTitle()} + + + + redirectTo({ destination: 'dashboard' })} + data-test-subj="createDashboardPromptButton" + aria-label={dashboardUnsavedListingStrings.getEditAriaLabel(getNewDashboardTitle())} + > + {dashboardUnsavedListingStrings.getEditTitle()} + + + + ) : ( + + {noItemsStrings.getCreateNewDashboardText()} + + ); + + return ( + + {isEditingFirstDashboard + ? noItemsStrings.getReadEditInProgressTitle() + : noItemsStrings.getReadEditTitle()} + + } + body={ + <> +

{noItemsStrings.getReadEditDashboardDescription()}

+ {!isEditingFirstDashboard && ( +

+ + core.application.navigateToApp('home', { + path: '#/tutorial_directory/sampleData', + }) + } + > + {noItemsStrings.getSampleDataLinkText()} + + ), + }} + /> +

+ )} + + } + actions={emptyAction} + /> + ); + }, [ + redirectTo, + createItem, + core.overlays, + core.application, + showWriteControls, + unsavedDashboardIds, + dashboardSessionStorage, + ]); const fetchItems = useCallback( (filter: string) => { @@ -233,60 +343,3 @@ const getTableColumns = ( ...(savedObjectsTagging ? [savedObjectsTagging.ui.getTableColumnDefinition()] : []), ] as unknown as Array>>; }; - -const getNoItemsMessage = ( - showWriteControls: boolean, - application: ApplicationStart, - createItem: () => void -) => { - if (!showWriteControls) { - return ( - {noItemsStrings.getReadonlyTitle()}} - body={

{noItemsStrings.getReadonlyBody()}

} - /> - ); - } - - return ( - {noItemsStrings.getReadEditTitle()}} - body={ - <> -

{noItemsStrings.getReadEditDashboardDescription()}

-

- - application.navigateToApp('home', { - path: '#/tutorial_directory/sampleData', - }) - } - > - {noItemsStrings.getSampleDataLinkText()} - - ), - }} - /> -

- - } - actions={ - - {noItemsStrings.getCreateNewDashboardText()} - - } - /> - ); -}; diff --git a/src/plugins/dashboard/public/application/top_nav/editor_menu.tsx b/src/plugins/dashboard/public/application/top_nav/editor_menu.tsx index 8a46a16c1bf0c..effbf8ce980d7 100644 --- a/src/plugins/dashboard/public/application/top_nav/editor_menu.tsx +++ b/src/plugins/dashboard/public/application/top_nav/editor_menu.tsx @@ -231,7 +231,7 @@ export const EditorMenu = ({ dashboardContainer, createNewVisType }: Props) => { i18n.translate('dashboard.createConfirmModal.unsavedChangesSubtitle', { - defaultMessage: 'You can continue editing or start with a blank dashboard.', + defaultMessage: 'Continue editing or start over with a blank dashboard.', }), getStartOverButtonText: () => i18n.translate('dashboard.createConfirmModal.confirmButtonLabel', { @@ -420,7 +420,7 @@ export const dashboardListingTable = { export const dashboardUnsavedListingStrings = { getUnsavedChangesTitle: (plural = false) => i18n.translate('dashboard.listing.unsaved.unsavedChangesTitle', { - defaultMessage: 'You have unsaved changes in the following {dash}.', + defaultMessage: 'You have unsaved changes in the following {dash}:', values: { dash: plural ? dashboardListingTable.getEntityNamePlural() @@ -469,17 +469,21 @@ export const noItemsStrings = { i18n.translate('dashboard.listing.createNewDashboard.title', { defaultMessage: 'Create your first dashboard', }), + getReadEditInProgressTitle: () => + i18n.translate('dashboard.listing.createNewDashboard.inProgressTitle', { + defaultMessage: 'Dashboard in progress', + }), getReadEditDashboardDescription: () => i18n.translate('dashboard.listing.createNewDashboard.combineDataViewFromKibanaAppDescription', { defaultMessage: - 'You can combine data views from any Kibana app into one dashboard and see everything in one place.', + 'Analyze all of your Elastic data in one place by creating a dashboard and adding visualizations.', }), getSampleDataLinkText: () => i18n.translate('dashboard.listing.createNewDashboard.sampleDataInstallLinkText', { - defaultMessage: `Install some sample data`, + defaultMessage: `Add some sample data`, }), getCreateNewDashboardText: () => i18n.translate('dashboard.listing.createNewDashboard.createButtonLabel', { - defaultMessage: `Create new dashboard`, + defaultMessage: `Create a dashboard`, }), }; diff --git a/src/plugins/discover/public/__mocks__/saved_search.ts b/src/plugins/discover/public/__mocks__/saved_search.ts index a488fe7e04c50..04c880e7e1928 100644 --- a/src/plugins/discover/public/__mocks__/saved_search.ts +++ b/src/plugins/discover/public/__mocks__/saved_search.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { SavedSearch } from '../saved_searches'; +import { SavedSearch } from '../services/saved_searches'; import { createSearchSourceMock } from '../../../data/public/mocks'; import { indexPatternMock } from './index_pattern'; import { indexPatternWithTimefieldMock } from './index_pattern_with_timefield'; diff --git a/src/plugins/discover/public/__mocks__/search_session.ts b/src/plugins/discover/public/__mocks__/search_session.ts index a9037217a303a..78a7a7f90a39e 100644 --- a/src/plugins/discover/public/__mocks__/search_session.ts +++ b/src/plugins/discover/public/__mocks__/search_session.ts @@ -8,7 +8,7 @@ import { createMemoryHistory } from 'history'; import { dataPluginMock } from '../../../data/public/mocks'; import { DataPublicPluginStart } from '../../../data/public'; -import { DiscoverSearchSessionManager } from '../application/apps/main/services/discover_search_session'; +import { DiscoverSearchSessionManager } from '../application/main/services/discover_search_session'; export function createSearchSessionMock() { const history = createMemoryHistory(); diff --git a/src/plugins/discover/public/application/apps/context/__mocks__/top_nav_menu.tsx b/src/plugins/discover/public/application/context/__mocks__/top_nav_menu.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/context/__mocks__/top_nav_menu.tsx rename to src/plugins/discover/public/application/context/__mocks__/top_nav_menu.tsx diff --git a/src/plugins/discover/public/application/apps/context/__mocks__/use_context_app_fetch.tsx b/src/plugins/discover/public/application/context/__mocks__/use_context_app_fetch.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/context/__mocks__/use_context_app_fetch.tsx rename to src/plugins/discover/public/application/context/__mocks__/use_context_app_fetch.tsx diff --git a/src/plugins/discover/public/application/apps/context/components/action_bar/_action_bar.scss b/src/plugins/discover/public/application/context/components/action_bar/_action_bar.scss similarity index 100% rename from src/plugins/discover/public/application/apps/context/components/action_bar/_action_bar.scss rename to src/plugins/discover/public/application/context/components/action_bar/_action_bar.scss diff --git a/src/plugins/discover/public/application/apps/context/components/action_bar/action_bar.test.tsx b/src/plugins/discover/public/application/context/components/action_bar/action_bar.test.tsx similarity index 97% rename from src/plugins/discover/public/application/apps/context/components/action_bar/action_bar.test.tsx rename to src/plugins/discover/public/application/context/components/action_bar/action_bar.test.tsx index de6d01b6a5273..cce6c7fbe6053 100644 --- a/src/plugins/discover/public/application/apps/context/components/action_bar/action_bar.test.tsx +++ b/src/plugins/discover/public/application/context/components/action_bar/action_bar.test.tsx @@ -10,7 +10,7 @@ import React from 'react'; import { mountWithIntl } from '@kbn/test/jest'; import { ActionBar, ActionBarProps } from './action_bar'; import { findTestSubject } from '@elastic/eui/lib/test'; -import { MAX_CONTEXT_SIZE, MIN_CONTEXT_SIZE } from '../../utils/constants'; +import { MAX_CONTEXT_SIZE, MIN_CONTEXT_SIZE } from '../../services/constants'; import { SurrDocType } from '../../services/context'; describe('Test Discover Context ActionBar for successor | predecessor records', () => { diff --git a/src/plugins/discover/public/application/apps/context/components/action_bar/action_bar.tsx b/src/plugins/discover/public/application/context/components/action_bar/action_bar.tsx similarity index 98% rename from src/plugins/discover/public/application/apps/context/components/action_bar/action_bar.tsx rename to src/plugins/discover/public/application/context/components/action_bar/action_bar.tsx index d9d56964358f8..4c1f7857e2b42 100644 --- a/src/plugins/discover/public/application/apps/context/components/action_bar/action_bar.tsx +++ b/src/plugins/discover/public/application/context/components/action_bar/action_bar.tsx @@ -20,7 +20,7 @@ import { } from '@elastic/eui'; import { ActionBarWarning } from './action_bar_warning'; import { SurrDocType } from '../../services/context'; -import { MAX_CONTEXT_SIZE, MIN_CONTEXT_SIZE } from '../../utils/constants'; +import { MAX_CONTEXT_SIZE, MIN_CONTEXT_SIZE } from '../../services/constants'; export interface ActionBarProps { /** diff --git a/src/plugins/discover/public/application/apps/context/components/action_bar/action_bar_warning.tsx b/src/plugins/discover/public/application/context/components/action_bar/action_bar_warning.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/context/components/action_bar/action_bar_warning.tsx rename to src/plugins/discover/public/application/context/components/action_bar/action_bar_warning.tsx diff --git a/src/plugins/discover/public/application/apps/context/components/context_error_message/context_error_message.test.tsx b/src/plugins/discover/public/application/context/components/context_error_message/context_error_message.test.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/context/components/context_error_message/context_error_message.test.tsx rename to src/plugins/discover/public/application/context/components/context_error_message/context_error_message.test.tsx diff --git a/src/plugins/discover/public/application/apps/context/components/context_error_message/context_error_message.tsx b/src/plugins/discover/public/application/context/components/context_error_message/context_error_message.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/context/components/context_error_message/context_error_message.tsx rename to src/plugins/discover/public/application/context/components/context_error_message/context_error_message.tsx diff --git a/src/plugins/discover/public/application/apps/context/components/context_error_message/index.ts b/src/plugins/discover/public/application/context/components/context_error_message/index.ts similarity index 100% rename from src/plugins/discover/public/application/apps/context/components/context_error_message/index.ts rename to src/plugins/discover/public/application/context/components/context_error_message/index.ts diff --git a/src/plugins/discover/public/application/apps/context/context_app.scss b/src/plugins/discover/public/application/context/context_app.scss similarity index 100% rename from src/plugins/discover/public/application/apps/context/context_app.scss rename to src/plugins/discover/public/application/context/context_app.scss diff --git a/src/plugins/discover/public/application/apps/context/context_app.test.tsx b/src/plugins/discover/public/application/context/context_app.test.tsx similarity index 88% rename from src/plugins/discover/public/application/apps/context/context_app.test.tsx rename to src/plugins/discover/public/application/context/context_app.test.tsx index d1c557f2839bc..7f78bb1c698ab 100644 --- a/src/plugins/discover/public/application/apps/context/context_app.test.tsx +++ b/src/plugins/discover/public/application/context/context_app.test.tsx @@ -9,16 +9,16 @@ import React from 'react'; import { waitFor } from '@testing-library/react'; import { mountWithIntl } from '@kbn/test/jest'; -import { createFilterManagerMock } from '../../../../../data/public/query/filter_manager/filter_manager.mock'; +import { createFilterManagerMock } from '../../../../data/public/query/filter_manager/filter_manager.mock'; import { mockTopNavMenu } from './__mocks__/top_nav_menu'; import { ContextAppContent } from './context_app_content'; -import { indexPatternMock } from '../../../__mocks__/index_pattern'; +import { indexPatternMock } from '../../__mocks__/index_pattern'; import { ContextApp } from './context_app'; -import { setServices } from '../../../kibana_services'; -import { DiscoverServices } from '../../../build_services'; -import { indexPatternsMock } from '../../../__mocks__/index_patterns'; +import { setServices } from '../../kibana_services'; +import { DiscoverServices } from '../../build_services'; +import { indexPatternsMock } from '../../__mocks__/index_patterns'; import { act } from 'react-dom/test-utils'; -import { uiSettingsMock } from '../../../__mocks__/ui_settings'; +import { uiSettingsMock } from '../../__mocks__/ui_settings'; const mockFilterManager = createFilterManagerMock(); const mockNavigationPlugin = { ui: { TopNavMenu: mockTopNavMenu } }; diff --git a/src/plugins/discover/public/application/apps/context/context_app.tsx b/src/plugins/discover/public/application/context/context_app.tsx similarity index 93% rename from src/plugins/discover/public/application/apps/context/context_app.tsx rename to src/plugins/discover/public/application/context/context_app.tsx index bfc13aac90e4b..293680b85c005 100644 --- a/src/plugins/discover/public/application/apps/context/context_app.tsx +++ b/src/plugins/discover/public/application/context/context_app.tsx @@ -12,20 +12,20 @@ import classNames from 'classnames'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiText, EuiPageContent, EuiPage, EuiSpacer } from '@elastic/eui'; import { cloneDeep } from 'lodash'; -import { esFilters } from '../../../../../data/public'; -import { DOC_TABLE_LEGACY, SEARCH_FIELDS_FROM_SOURCE } from '../../../../common'; +import { esFilters } from '../../../../data/public'; +import { DOC_TABLE_LEGACY, SEARCH_FIELDS_FROM_SOURCE } from '../../../common'; import { ContextErrorMessage } from './components/context_error_message'; -import { IndexPattern, IndexPatternField } from '../../../../../data/common'; +import { IndexPattern, IndexPatternField } from '../../../../data/common'; import { LoadingStatus } from './services/context_query_state'; -import { getServices } from '../../../kibana_services'; +import { getServices } from '../../kibana_services'; import { AppState, isEqualFilters } from './services/context_state'; -import { useColumns } from '../../helpers/use_data_grid_columns'; +import { useColumns } from '../../utils/use_data_grid_columns'; import { useContextAppState } from './utils/use_context_app_state'; import { useContextAppFetch } from './utils/use_context_app_fetch'; -import { popularizeField } from '../../helpers/popularize_field'; +import { popularizeField } from '../../utils/popularize_field'; import { ContextAppContent } from './context_app_content'; import { SurrDocType } from './services/context'; -import { DocViewFilterFn } from '../../doc_views/doc_views_types'; +import { DocViewFilterFn } from '../../services/doc_views/doc_views_types'; const ContextAppContentMemoized = memo(ContextAppContent); diff --git a/src/plugins/discover/public/application/apps/context/context_app_content.test.tsx b/src/plugins/discover/public/application/context/context_app_content.test.tsx similarity index 91% rename from src/plugins/discover/public/application/apps/context/context_app_content.test.tsx rename to src/plugins/discover/public/application/context/context_app_content.test.tsx index 9b1c47d37203f..5ec89c8e267ea 100644 --- a/src/plugins/discover/public/application/apps/context/context_app_content.test.tsx +++ b/src/plugins/discover/public/application/context/context_app_content.test.tsx @@ -13,13 +13,13 @@ import { ActionBar } from './components/action_bar/action_bar'; import { AppState, GetStateReturn } from './services/context_state'; import { SortDirection } from 'src/plugins/data/common'; import { ContextAppContent, ContextAppContentProps } from './context_app_content'; -import { getServices, setServices } from '../../../kibana_services'; +import { getServices, setServices } from '../../kibana_services'; import { LoadingStatus } from './services/context_query_state'; -import { indexPatternMock } from '../../../__mocks__/index_pattern'; +import { indexPatternMock } from '../../__mocks__/index_pattern'; import { DiscoverGrid } from '../../components/discover_grid/discover_grid'; -import { discoverServiceMock } from '../../../__mocks__/services'; -import { DocTableWrapper } from '../main/components/doc_table/doc_table_wrapper'; -import { EsHitRecordList } from '../../types'; +import { discoverServiceMock } from '../../__mocks__/services'; +import { DocTableWrapper } from '../../components/doc_table/doc_table_wrapper'; +import { EsHitRecordList } from '../types'; describe('ContextAppContent test', () => { let hit; diff --git a/src/plugins/discover/public/application/apps/context/context_app_content.tsx b/src/plugins/discover/public/application/context/context_app_content.tsx similarity index 91% rename from src/plugins/discover/public/application/apps/context/context_app_content.tsx rename to src/plugins/discover/public/application/context/context_app_content.tsx index c8f3cfe0a568f..0d24e8129a8dd 100644 --- a/src/plugins/discover/public/application/apps/context/context_app_content.tsx +++ b/src/plugins/discover/public/application/context/context_app_content.tsx @@ -9,20 +9,20 @@ import React, { useState, Fragment, useMemo, useCallback } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiHorizontalRule, EuiText } from '@elastic/eui'; -import { CONTEXT_STEP_SETTING, DOC_HIDE_TIME_COLUMN_SETTING } from '../../../../common'; -import { IndexPattern } from '../../../../../data/common'; -import { SortDirection } from '../../../../../data/public'; +import { CONTEXT_STEP_SETTING, DOC_HIDE_TIME_COLUMN_SETTING } from '../../../common'; +import { IndexPattern } from '../../../../data/common'; +import { SortDirection } from '../../../../data/public'; import { LoadingStatus } from './services/context_query_state'; import { ActionBar } from './components/action_bar/action_bar'; import { DiscoverGrid } from '../../components/discover_grid/discover_grid'; -import { DocViewFilterFn, ElasticSearchHit } from '../../doc_views/doc_views_types'; +import { DocViewFilterFn, ElasticSearchHit } from '../../services/doc_views/doc_views_types'; import { AppState } from './services/context_state'; import { SurrDocType } from './services/context'; -import { DiscoverServices } from '../../../build_services'; -import { MAX_CONTEXT_SIZE, MIN_CONTEXT_SIZE } from './utils/constants'; -import { DocTableContext } from '../main/components/doc_table/doc_table_context'; -import { EsHitRecordList } from '../../types'; -import { SortPairArr } from '../main/components/doc_table/lib/get_sort'; +import { DiscoverServices } from '../../build_services'; +import { MAX_CONTEXT_SIZE, MIN_CONTEXT_SIZE } from './services/constants'; +import { DocTableContext } from '../../components/doc_table/doc_table_context'; +import { EsHitRecordList } from '../types'; +import { SortPairArr } from '../../components/doc_table/lib/get_sort'; export interface ContextAppContentProps { columns: string[]; diff --git a/src/plugins/discover/public/application/apps/context/context_app_route.tsx b/src/plugins/discover/public/application/context/context_app_route.tsx similarity index 91% rename from src/plugins/discover/public/application/apps/context/context_app_route.tsx rename to src/plugins/discover/public/application/context/context_app_route.tsx index 6c4722418be14..9d47d211489b0 100644 --- a/src/plugins/discover/public/application/apps/context/context_app_route.tsx +++ b/src/plugins/discover/public/application/context/context_app_route.tsx @@ -10,11 +10,11 @@ import { useParams } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; import { EuiEmptyPrompt } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { DiscoverServices } from '../../../build_services'; +import { DiscoverServices } from '../../build_services'; import { ContextApp } from './context_app'; -import { getRootBreadcrumbs } from '../../helpers/breadcrumbs'; +import { getRootBreadcrumbs } from '../../utils/breadcrumbs'; import { LoadingIndicator } from '../../components/common/loading_indicator'; -import { useIndexPattern } from '../../helpers/use_index_pattern'; +import { useIndexPattern } from '../../utils/use_index_pattern'; export interface ContextAppProps { /** diff --git a/src/plugins/discover/public/application/apps/context/index.ts b/src/plugins/discover/public/application/context/index.ts similarity index 100% rename from src/plugins/discover/public/application/apps/context/index.ts rename to src/plugins/discover/public/application/context/index.ts diff --git a/src/plugins/discover/public/application/apps/context/services/__snapshots__/context.test.ts.snap b/src/plugins/discover/public/application/context/services/__snapshots__/context.test.ts.snap similarity index 100% rename from src/plugins/discover/public/application/apps/context/services/__snapshots__/context.test.ts.snap rename to src/plugins/discover/public/application/context/services/__snapshots__/context.test.ts.snap diff --git a/src/plugins/discover/public/application/apps/context/services/_stubs.ts b/src/plugins/discover/public/application/context/services/_stubs.ts similarity index 98% rename from src/plugins/discover/public/application/apps/context/services/_stubs.ts rename to src/plugins/discover/public/application/context/services/_stubs.ts index e8d09e548c07a..df53523c367ae 100644 --- a/src/plugins/discover/public/application/apps/context/services/_stubs.ts +++ b/src/plugins/discover/public/application/context/services/_stubs.ts @@ -9,7 +9,7 @@ import sinon from 'sinon'; import moment from 'moment'; -import { EsHitRecordList } from '../../../types'; +import { EsHitRecordList } from '../../types'; type SortHit = { [key in string]: number; // timeField name diff --git a/src/plugins/discover/public/application/apps/context/services/anchor.test.ts b/src/plugins/discover/public/application/context/services/anchor.test.ts similarity index 96% rename from src/plugins/discover/public/application/apps/context/services/anchor.test.ts rename to src/plugins/discover/public/application/context/services/anchor.test.ts index 8886c8ab11f64..69c962b0c857e 100644 --- a/src/plugins/discover/public/application/apps/context/services/anchor.test.ts +++ b/src/plugins/discover/public/application/context/services/anchor.test.ts @@ -6,12 +6,12 @@ * Side Public License, v 1. */ -import { IndexPattern, SortDirection } from '../../../../../../data/public'; +import { IndexPattern, SortDirection } from '../../../../../data/public'; import { createSearchSourceStub } from './_stubs'; import { fetchAnchor, updateSearchSource } from './anchor'; -import { indexPatternMock } from '../../../../__mocks__/index_pattern'; -import { savedSearchMock } from '../../../../__mocks__/saved_search'; -import { EsHitRecordList } from '../../../types'; +import { indexPatternMock } from '../../../__mocks__/index_pattern'; +import { savedSearchMock } from '../../../__mocks__/saved_search'; +import { EsHitRecordList } from '../../types'; describe('context app', function () { // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/src/plugins/discover/public/application/apps/context/services/anchor.ts b/src/plugins/discover/public/application/context/services/anchor.ts similarity index 96% rename from src/plugins/discover/public/application/apps/context/services/anchor.ts rename to src/plugins/discover/public/application/context/services/anchor.ts index f262d440b8a28..a42c0285bc197 100644 --- a/src/plugins/discover/public/application/apps/context/services/anchor.ts +++ b/src/plugins/discover/public/application/context/services/anchor.ts @@ -8,8 +8,8 @@ import { i18n } from '@kbn/i18n'; -import { ISearchSource, EsQuerySortValue, IndexPattern } from '../../../../../../data/public'; -import { EsHitRecord } from '../../../types'; +import { ISearchSource, EsQuerySortValue, IndexPattern } from '../../../../../data/public'; +import { EsHitRecord } from '../../types'; export async function fetchAnchor( anchorId: string, diff --git a/src/plugins/discover/public/application/apps/context/utils/constants.ts b/src/plugins/discover/public/application/context/services/constants.ts similarity index 100% rename from src/plugins/discover/public/application/apps/context/utils/constants.ts rename to src/plugins/discover/public/application/context/services/constants.ts diff --git a/src/plugins/discover/public/application/apps/context/services/context.predecessors.test.ts b/src/plugins/discover/public/application/context/services/context.predecessors.test.ts similarity index 97% rename from src/plugins/discover/public/application/apps/context/services/context.predecessors.test.ts rename to src/plugins/discover/public/application/context/services/context.predecessors.test.ts index 9bcf6f9c90d2c..1d343a2765da6 100644 --- a/src/plugins/discover/public/application/apps/context/services/context.predecessors.test.ts +++ b/src/plugins/discover/public/application/context/services/context.predecessors.test.ts @@ -11,10 +11,10 @@ import { get, last } from 'lodash'; import { IndexPattern, SortDirection } from 'src/plugins/data/common'; import { createContextSearchSourceStub } from './_stubs'; import { fetchSurroundingDocs, SurrDocType } from './context'; -import { setServices } from '../../../../kibana_services'; -import { Query } from '../../../../../../data/public'; -import { DiscoverServices } from '../../../../build_services'; -import { EsHitRecord, EsHitRecordList } from '../../../types'; +import { setServices } from '../../../kibana_services'; +import { Query } from '../../../../../data/public'; +import { DiscoverServices } from '../../../build_services'; +import { EsHitRecord, EsHitRecordList } from '../../types'; const MS_PER_DAY = 24 * 60 * 60 * 1000; const ANCHOR_TIMESTAMP = new Date(MS_PER_DAY).toJSON(); diff --git a/src/plugins/discover/public/application/apps/context/services/context.successors.test.ts b/src/plugins/discover/public/application/context/services/context.successors.test.ts similarity index 97% rename from src/plugins/discover/public/application/apps/context/services/context.successors.test.ts rename to src/plugins/discover/public/application/context/services/context.successors.test.ts index 169d969753645..975d951f49ef3 100644 --- a/src/plugins/discover/public/application/apps/context/services/context.successors.test.ts +++ b/src/plugins/discover/public/application/context/services/context.successors.test.ts @@ -10,11 +10,11 @@ import moment from 'moment'; import { get, last } from 'lodash'; import { IndexPattern, SortDirection } from 'src/plugins/data/common'; import { createContextSearchSourceStub } from './_stubs'; -import { setServices } from '../../../../kibana_services'; -import { Query } from '../../../../../../data/public'; +import { setServices } from '../../../kibana_services'; +import { Query } from '../../../../../data/public'; import { fetchSurroundingDocs, SurrDocType } from './context'; -import { DiscoverServices } from '../../../../build_services'; -import { EsHitRecord, EsHitRecordList } from '../../../types'; +import { DiscoverServices } from '../../../build_services'; +import { EsHitRecord, EsHitRecordList } from '../../types'; const MS_PER_DAY = 24 * 60 * 60 * 1000; const ANCHOR_TIMESTAMP = new Date(MS_PER_DAY).toJSON(); diff --git a/src/plugins/discover/public/application/apps/context/services/context.test.ts b/src/plugins/discover/public/application/context/services/context.test.ts similarity index 87% rename from src/plugins/discover/public/application/apps/context/services/context.test.ts rename to src/plugins/discover/public/application/context/services/context.test.ts index 5ad9c02871dca..df5a279dfe927 100644 --- a/src/plugins/discover/public/application/apps/context/services/context.test.ts +++ b/src/plugins/discover/public/application/context/services/context.test.ts @@ -7,8 +7,8 @@ */ import { updateSearchSource } from './context'; -import { indexPatternMock } from '../../../../__mocks__/index_pattern'; -import { createSearchSourceMock } from '../../../../../../data/public/mocks'; +import { indexPatternMock } from '../../../__mocks__/index_pattern'; +import { createSearchSourceMock } from '../../../../../data/public/mocks'; describe('context api', function () { test('createSearchSource when useFieldsApi is true', () => { diff --git a/src/plugins/discover/public/application/apps/context/services/context.ts b/src/plugins/discover/public/application/context/services/context.ts similarity index 86% rename from src/plugins/discover/public/application/apps/context/services/context.ts rename to src/plugins/discover/public/application/context/services/context.ts index 257ae2dcce834..f8af5468cbad5 100644 --- a/src/plugins/discover/public/application/apps/context/services/context.ts +++ b/src/plugins/discover/public/application/context/services/context.ts @@ -6,14 +6,14 @@ * Side Public License, v 1. */ import { Filter, IndexPattern, ISearchSource } from 'src/plugins/data/public'; -import { reverseSortDir, SortDirection } from './utils/sorting'; -import { convertIsoToMillis, extractNanos } from './utils/date_conversion'; -import { fetchHitsInInterval } from './utils/fetch_hits_in_interval'; -import { generateIntervals } from './utils/generate_intervals'; -import { getEsQuerySearchAfter } from './utils/get_es_query_search_after'; -import { getEsQuerySort } from './utils/get_es_query_sort'; -import { getServices } from '../../../../kibana_services'; -import { EsHitRecord, EsHitRecordList } from '../../../types'; +import { reverseSortDir, SortDirection } from '../utils/sorting'; +import { convertIsoToMillis, extractNanos } from '../utils/date_conversion'; +import { fetchHitsInInterval } from '../utils/fetch_hits_in_interval'; +import { generateIntervals } from '../utils/generate_intervals'; +import { getEsQuerySearchAfter } from '../utils/get_es_query_search_after'; +import { getEsQuerySort } from '../utils/get_es_query_sort'; +import { getServices } from '../../../kibana_services'; +import { EsHitRecord, EsHitRecordList } from '../../types'; export enum SurrDocType { SUCCESSORS = 'successors', diff --git a/src/plugins/discover/public/application/apps/context/services/context_query_state.ts b/src/plugins/discover/public/application/context/services/context_query_state.ts similarity index 95% rename from src/plugins/discover/public/application/apps/context/services/context_query_state.ts rename to src/plugins/discover/public/application/context/services/context_query_state.ts index 132b74647f66e..3a6a4c0959ea6 100644 --- a/src/plugins/discover/public/application/apps/context/services/context_query_state.ts +++ b/src/plugins/discover/public/application/context/services/context_query_state.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { EsHitRecord, EsHitRecordList } from '../../../types'; +import { EsHitRecord, EsHitRecordList } from '../../types'; export interface ContextFetchState { /** diff --git a/src/plugins/discover/public/application/apps/context/services/context_state.test.ts b/src/plugins/discover/public/application/context/services/context_state.test.ts similarity index 96% rename from src/plugins/discover/public/application/apps/context/services/context_state.test.ts rename to src/plugins/discover/public/application/context/services/context_state.test.ts index 3df8ab710729f..8f564d56c1042 100644 --- a/src/plugins/discover/public/application/apps/context/services/context_state.test.ts +++ b/src/plugins/discover/public/application/context/services/context_state.test.ts @@ -9,9 +9,9 @@ import { IUiSettingsClient } from 'kibana/public'; import { getState } from './context_state'; import { createBrowserHistory, History } from 'history'; -import { FilterManager, Filter } from '../../../../../../data/public'; -import { coreMock } from '../../../../../../../core/public/mocks'; -import { SEARCH_FIELDS_FROM_SOURCE } from '../../../../../common'; +import { FilterManager, Filter } from '../../../../../data/public'; +import { coreMock } from '../../../../../../core/public/mocks'; +import { SEARCH_FIELDS_FROM_SOURCE } from '../../../../common'; const setupMock = coreMock.createSetup(); diff --git a/src/plugins/discover/public/application/apps/context/services/context_state.ts b/src/plugins/discover/public/application/context/services/context_state.ts similarity index 98% rename from src/plugins/discover/public/application/apps/context/services/context_state.ts rename to src/plugins/discover/public/application/context/services/context_state.ts index 87f7cf00bafcf..8fb79f6f011c7 100644 --- a/src/plugins/discover/public/application/apps/context/services/context_state.ts +++ b/src/plugins/discover/public/application/context/services/context_state.ts @@ -15,9 +15,9 @@ import { syncStates, withNotifyOnErrors, ReduxLikeStateContainer, -} from '../../../../../../kibana_utils/public'; -import { esFilters, FilterManager, Filter } from '../../../../../../data/public'; -import { handleSourceColumnState } from '../../../helpers/state_helpers'; +} from '../../../../../kibana_utils/public'; +import { esFilters, FilterManager, Filter } from '../../../../../data/public'; +import { handleSourceColumnState } from '../../../utils/state_helpers'; export interface AppState { /** diff --git a/src/plugins/discover/public/application/apps/context/services/utils/date_conversion.test.ts b/src/plugins/discover/public/application/context/utils/date_conversion.test.ts similarity index 100% rename from src/plugins/discover/public/application/apps/context/services/utils/date_conversion.test.ts rename to src/plugins/discover/public/application/context/utils/date_conversion.test.ts diff --git a/src/plugins/discover/public/application/apps/context/services/utils/date_conversion.ts b/src/plugins/discover/public/application/context/utils/date_conversion.ts similarity index 100% rename from src/plugins/discover/public/application/apps/context/services/utils/date_conversion.ts rename to src/plugins/discover/public/application/context/utils/date_conversion.ts diff --git a/src/plugins/discover/public/application/apps/context/services/utils/fetch_hits_in_interval.ts b/src/plugins/discover/public/application/context/utils/fetch_hits_in_interval.ts similarity index 95% rename from src/plugins/discover/public/application/apps/context/services/utils/fetch_hits_in_interval.ts rename to src/plugins/discover/public/application/context/utils/fetch_hits_in_interval.ts index 4cfbee2dc02bc..3fc2716114513 100644 --- a/src/plugins/discover/public/application/apps/context/services/utils/fetch_hits_in_interval.ts +++ b/src/plugins/discover/public/application/context/utils/fetch_hits_in_interval.ts @@ -6,11 +6,11 @@ * Side Public License, v 1. */ -import { ISearchSource, EsQuerySortValue, SortDirection } from '../../../../../../../data/public'; +import { ISearchSource, EsQuerySortValue, SortDirection } from '../../../../../data/public'; import { convertTimeValueToIso } from './date_conversion'; import { IntervalValue } from './generate_intervals'; import { EsQuerySearchAfter } from './get_es_query_search_after'; -import { EsHitRecord, EsHitRecordList } from '../../../../types'; +import { EsHitRecord, EsHitRecordList } from '../../types'; interface RangeQuery { format: string; diff --git a/src/plugins/discover/public/application/apps/context/services/utils/generate_intervals.ts b/src/plugins/discover/public/application/context/utils/generate_intervals.ts similarity index 93% rename from src/plugins/discover/public/application/apps/context/services/utils/generate_intervals.ts rename to src/plugins/discover/public/application/context/utils/generate_intervals.ts index 47952f4f84759..5adeb31444ee7 100644 --- a/src/plugins/discover/public/application/apps/context/services/utils/generate_intervals.ts +++ b/src/plugins/discover/public/application/context/utils/generate_intervals.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ -import { SortDirection } from '../../../../../../../data/public'; -import { SurrDocType } from '../context'; +import { SortDirection } from '../../../../../data/public'; +import { SurrDocType } from '../services/context'; export type IntervalValue = number | null; diff --git a/src/plugins/discover/public/application/apps/context/services/utils/get_es_query_search_after.ts b/src/plugins/discover/public/application/context/utils/get_es_query_search_after.ts similarity index 94% rename from src/plugins/discover/public/application/apps/context/services/utils/get_es_query_search_after.ts rename to src/plugins/discover/public/application/context/utils/get_es_query_search_after.ts index 721459fee08f8..85a68376fe43b 100644 --- a/src/plugins/discover/public/application/apps/context/services/utils/get_es_query_search_after.ts +++ b/src/plugins/discover/public/application/context/utils/get_es_query_search_after.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ -import { SurrDocType } from '../context'; -import { EsHitRecord, EsHitRecordList } from '../../../../types'; +import { SurrDocType } from '../services/context'; +import { EsHitRecord, EsHitRecordList } from '../../types'; export type EsQuerySearchAfter = [string | number, string | number]; diff --git a/src/plugins/discover/public/application/apps/context/services/utils/get_es_query_sort.ts b/src/plugins/discover/public/application/context/utils/get_es_query_sort.ts similarity index 100% rename from src/plugins/discover/public/application/apps/context/services/utils/get_es_query_sort.ts rename to src/plugins/discover/public/application/context/utils/get_es_query_sort.ts diff --git a/src/plugins/discover/public/application/apps/context/services/utils/sorting.test.ts b/src/plugins/discover/public/application/context/utils/sorting.test.ts similarity index 100% rename from src/plugins/discover/public/application/apps/context/services/utils/sorting.test.ts rename to src/plugins/discover/public/application/context/utils/sorting.test.ts diff --git a/src/plugins/discover/public/application/apps/context/services/utils/sorting.ts b/src/plugins/discover/public/application/context/utils/sorting.ts similarity index 100% rename from src/plugins/discover/public/application/apps/context/services/utils/sorting.ts rename to src/plugins/discover/public/application/context/utils/sorting.ts diff --git a/src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts b/src/plugins/discover/public/application/context/utils/use_context_app_fetch.test.ts similarity index 94% rename from src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts rename to src/plugins/discover/public/application/context/utils/use_context_app_fetch.test.ts index b3626f9c06f10..cd7bcd810dc39 100644 --- a/src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.test.ts +++ b/src/plugins/discover/public/application/context/utils/use_context_app_fetch.test.ts @@ -7,10 +7,10 @@ */ import { act, renderHook } from '@testing-library/react-hooks'; -import { setServices, getServices } from '../../../../kibana_services'; -import { createFilterManagerMock } from '../../../../../../data/public/query/filter_manager/filter_manager.mock'; -import { CONTEXT_TIE_BREAKER_FIELDS_SETTING } from '../../../../../common'; -import { DiscoverServices } from '../../../../build_services'; +import { setServices, getServices } from '../../../kibana_services'; +import { createFilterManagerMock } from '../../../../../data/public/query/filter_manager/filter_manager.mock'; +import { CONTEXT_TIE_BREAKER_FIELDS_SETTING } from '../../../../common'; +import { DiscoverServices } from '../../../build_services'; import { FailureReason, LoadingStatus } from '../services/context_query_state'; import { ContextAppFetchProps, useContextAppFetch } from './use_context_app_fetch'; import { @@ -18,9 +18,9 @@ import { mockPredecessorHits, mockSuccessorHits, } from '../__mocks__/use_context_app_fetch'; -import { indexPatternWithTimefieldMock } from '../../../../__mocks__/index_pattern_with_timefield'; +import { indexPatternWithTimefieldMock } from '../../../__mocks__/index_pattern_with_timefield'; import { createContextSearchSourceStub } from '../services/_stubs'; -import { IndexPattern } from '../../../../../../data_views/common'; +import { IndexPattern } from '../../../../../data_views/common'; const mockFilterManager = createFilterManagerMock(); diff --git a/src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.tsx b/src/plugins/discover/public/application/context/utils/use_context_app_fetch.tsx similarity index 93% rename from src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.tsx rename to src/plugins/discover/public/application/context/utils/use_context_app_fetch.tsx index ed3b4e8ed5b5a..acc11ccdbe8f9 100644 --- a/src/plugins/discover/public/application/apps/context/utils/use_context_app_fetch.tsx +++ b/src/plugins/discover/public/application/context/utils/use_context_app_fetch.tsx @@ -7,12 +7,12 @@ */ import React, { useCallback, useMemo, useState } from 'react'; import { i18n } from '@kbn/i18n'; -import { CONTEXT_TIE_BREAKER_FIELDS_SETTING } from '../../../../../common'; -import { DiscoverServices } from '../../../../build_services'; +import { CONTEXT_TIE_BREAKER_FIELDS_SETTING } from '../../../../common'; +import { DiscoverServices } from '../../../build_services'; import { fetchAnchor } from '../services/anchor'; import { fetchSurroundingDocs, SurrDocType } from '../services/context'; -import { MarkdownSimple, toMountPoint } from '../../../../../../kibana_react/public'; -import { IndexPattern, SortDirection } from '../../../../../../data/public'; +import { MarkdownSimple, toMountPoint } from '../../../../../kibana_react/public'; +import { IndexPattern, SortDirection } from '../../../../../data/public'; import { ContextFetchState, FailureReason, @@ -20,8 +20,8 @@ import { LoadingStatus, } from '../services/context_query_state'; import { AppState } from '../services/context_state'; -import { getFirstSortableField } from '../services/utils/sorting'; -import { EsHitRecord } from '../../../types'; +import { getFirstSortableField } from './sorting'; +import { EsHitRecord } from '../../types'; const createError = (statusKey: string, reason: FailureReason, error?: Error) => ({ [statusKey]: { value: LoadingStatus.FAILED, error, reason }, diff --git a/src/plugins/discover/public/application/apps/context/utils/use_context_app_state.ts b/src/plugins/discover/public/application/context/utils/use_context_app_state.ts similarity index 94% rename from src/plugins/discover/public/application/apps/context/utils/use_context_app_state.ts rename to src/plugins/discover/public/application/context/utils/use_context_app_state.ts index 56701f17c7a63..9accdb363af92 100644 --- a/src/plugins/discover/public/application/apps/context/utils/use_context_app_state.ts +++ b/src/plugins/discover/public/application/context/utils/use_context_app_state.ts @@ -8,8 +8,8 @@ import { useEffect, useMemo, useState } from 'react'; import { cloneDeep } from 'lodash'; -import { CONTEXT_DEFAULT_SIZE_SETTING } from '../../../../../common'; -import { DiscoverServices } from '../../../../build_services'; +import { CONTEXT_DEFAULT_SIZE_SETTING } from '../../../../common'; +import { DiscoverServices } from '../../../build_services'; import { AppState, getState } from '../services/context_state'; export function useContextAppState({ services }: { services: DiscoverServices }) { diff --git a/src/plugins/discover/public/application/discover_router.test.tsx b/src/plugins/discover/public/application/discover_router.test.tsx index 59aede76c6866..dad796bc7c5f6 100644 --- a/src/plugins/discover/public/application/discover_router.test.tsx +++ b/src/plugins/discover/public/application/discover_router.test.tsx @@ -11,10 +11,10 @@ import { Route, RouteProps } from 'react-router-dom'; import { createSearchSessionMock } from '../__mocks__/search_session'; import { discoverServiceMock as mockDiscoverServices } from '../__mocks__/services'; import { discoverRouter } from './discover_router'; -import { DiscoverMainRoute } from './apps/main'; -import { DiscoverMainProps } from './apps/main/discover_main_route'; -import { SingleDocRoute } from './apps/doc'; -import { ContextAppRoute } from './apps/context'; +import { DiscoverMainRoute } from './main'; +import { DiscoverMainProps } from './main/discover_main_route'; +import { SingleDocRoute } from './doc'; +import { ContextAppRoute } from './context'; const pathMap: Record = {}; let mainRouteProps: DiscoverMainProps; diff --git a/src/plugins/discover/public/application/discover_router.tsx b/src/plugins/discover/public/application/discover_router.tsx index b3fe36358bbd4..6f88c28b52bf9 100644 --- a/src/plugins/discover/public/application/discover_router.tsx +++ b/src/plugins/discover/public/application/discover_router.tsx @@ -10,12 +10,12 @@ import { Redirect, Route, Router, Switch } from 'react-router-dom'; import React from 'react'; import { History } from 'history'; import { KibanaContextProvider } from '../../../kibana_react/public'; -import { ContextAppRoute } from './apps/context'; -import { SingleDocRoute } from './apps/doc'; -import { DiscoverMainRoute } from './apps/main'; -import { NotFoundRoute } from './apps/not_found'; +import { ContextAppRoute } from './context'; +import { SingleDocRoute } from './doc'; +import { DiscoverMainRoute } from './main'; +import { NotFoundRoute } from './not_found'; import { DiscoverServices } from '../build_services'; -import { DiscoverMainProps } from './apps/main/discover_main_route'; +import { DiscoverMainProps } from './main/discover_main_route'; export const discoverRouter = (services: DiscoverServices, history: History) => { const mainRouteProps: DiscoverMainProps = { diff --git a/src/plugins/discover/public/application/apps/doc/components/doc.test.tsx b/src/plugins/discover/public/application/doc/components/doc.test.tsx similarity index 95% rename from src/plugins/discover/public/application/apps/doc/components/doc.test.tsx rename to src/plugins/discover/public/application/doc/components/doc.test.tsx index 68c012ddd92e9..4131a004d299b 100644 --- a/src/plugins/discover/public/application/apps/doc/components/doc.test.tsx +++ b/src/plugins/discover/public/application/doc/components/doc.test.tsx @@ -13,12 +13,12 @@ import { mountWithIntl } from '@kbn/test/jest'; import { ReactWrapper } from 'enzyme'; import { findTestSubject } from '@elastic/eui/lib/test'; import { Doc, DocProps } from './doc'; -import { SEARCH_FIELDS_FROM_SOURCE as mockSearchFieldsFromSource } from '../../../../../common'; -import { indexPatternMock } from '../../../../__mocks__/index_pattern'; +import { SEARCH_FIELDS_FROM_SOURCE as mockSearchFieldsFromSource } from '../../../../common'; +import { indexPatternMock } from '../../../__mocks__/index_pattern'; const mockSearchApi = jest.fn(); -jest.mock('../../../../kibana_services', () => { +jest.mock('../../../kibana_services', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any let registry: any[] = []; diff --git a/src/plugins/discover/public/application/apps/doc/components/doc.tsx b/src/plugins/discover/public/application/doc/components/doc.tsx similarity index 94% rename from src/plugins/discover/public/application/apps/doc/components/doc.tsx rename to src/plugins/discover/public/application/doc/components/doc.tsx index 7ccf77d2a29d4..3cb416ae8ef46 100644 --- a/src/plugins/discover/public/application/apps/doc/components/doc.tsx +++ b/src/plugins/discover/public/application/doc/components/doc.tsx @@ -10,10 +10,10 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiCallOut, EuiLink, EuiLoadingSpinner, EuiPageContent, EuiPage } from '@elastic/eui'; import { IndexPattern } from 'src/plugins/data/public'; -import { getServices } from '../../../../kibana_services'; -import { DocViewer } from '../../../components/doc_viewer/doc_viewer'; +import { getServices } from '../../../kibana_services'; +import { DocViewer } from '../../../services/doc_views/components/doc_viewer'; import { ElasticRequestState } from '../types'; -import { useEsDocSearch } from '../../../services/use_es_doc_search'; +import { useEsDocSearch } from '../../../utils/use_es_doc_search'; export interface DocProps { /** diff --git a/src/plugins/discover/public/application/apps/doc/index.ts b/src/plugins/discover/public/application/doc/index.ts similarity index 100% rename from src/plugins/discover/public/application/apps/doc/index.ts rename to src/plugins/discover/public/application/doc/index.ts diff --git a/src/plugins/discover/public/application/apps/doc/single_doc_route.tsx b/src/plugins/discover/public/application/doc/single_doc_route.tsx similarity index 92% rename from src/plugins/discover/public/application/apps/doc/single_doc_route.tsx rename to src/plugins/discover/public/application/doc/single_doc_route.tsx index aef928d523515..b9887a6f16cdf 100644 --- a/src/plugins/discover/public/application/apps/doc/single_doc_route.tsx +++ b/src/plugins/discover/public/application/doc/single_doc_route.tsx @@ -9,11 +9,11 @@ import React, { useEffect } from 'react'; import { useLocation, useParams } from 'react-router-dom'; import { EuiEmptyPrompt } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { DiscoverServices } from '../../../build_services'; -import { getRootBreadcrumbs } from '../../helpers/breadcrumbs'; +import { DiscoverServices } from '../../build_services'; +import { getRootBreadcrumbs } from '../../utils/breadcrumbs'; import { Doc } from './components/doc'; import { LoadingIndicator } from '../../components/common/loading_indicator'; -import { useIndexPattern } from '../../helpers/use_index_pattern'; +import { useIndexPattern } from '../../utils/use_index_pattern'; export interface SingleDocRouteProps { /** diff --git a/src/plugins/discover/public/application/apps/doc/types.ts b/src/plugins/discover/public/application/doc/types.ts similarity index 100% rename from src/plugins/discover/public/application/apps/doc/types.ts rename to src/plugins/discover/public/application/doc/types.ts diff --git a/src/plugins/discover/public/application/apps/main/components/chart/discover_chart.test.tsx b/src/plugins/discover/public/application/main/components/chart/discover_chart.test.tsx similarity index 86% rename from src/plugins/discover/public/application/apps/main/components/chart/discover_chart.test.tsx rename to src/plugins/discover/public/application/main/components/chart/discover_chart.test.tsx index f7a383be76b9e..cb6d96f049c51 100644 --- a/src/plugins/discover/public/application/apps/main/components/chart/discover_chart.test.tsx +++ b/src/plugins/discover/public/application/main/components/chart/discover_chart.test.tsx @@ -9,17 +9,17 @@ import React from 'react'; import { Subject, BehaviorSubject } from 'rxjs'; import { mountWithIntl } from '@kbn/test/jest'; -import { setHeaderActionMenuMounter } from '../../../../../kibana_services'; -import { esHits } from '../../../../../__mocks__/es_hits'; -import { savedSearchMock } from '../../../../../__mocks__/saved_search'; -import { createSearchSourceMock } from '../../../../../../../data/common/search/search_source/mocks'; +import { setHeaderActionMenuMounter } from '../../../../kibana_services'; +import { esHits } from '../../../../__mocks__/es_hits'; +import { savedSearchMock } from '../../../../__mocks__/saved_search'; +import { createSearchSourceMock } from '../../../../../../data/common/search/search_source/mocks'; import { GetStateReturn } from '../../services/discover_state'; -import { DataCharts$, DataTotalHits$ } from '../../services/use_saved_search'; -import { discoverServiceMock } from '../../../../../__mocks__/services'; -import { FetchStatus } from '../../../../types'; +import { DataCharts$, DataTotalHits$ } from '../../utils/use_saved_search'; +import { discoverServiceMock } from '../../../../__mocks__/services'; +import { FetchStatus } from '../../../types'; import { Chart } from './point_series'; import { DiscoverChart } from './discover_chart'; -import { VIEW_MODE } from '../view_mode_toggle'; +import { VIEW_MODE } from '../../../../components/view_mode_toggle'; setHeaderActionMenuMounter(jest.fn()); diff --git a/src/plugins/discover/public/application/apps/main/components/chart/discover_chart.tsx b/src/plugins/discover/public/application/main/components/chart/discover_chart.tsx similarity index 93% rename from src/plugins/discover/public/application/apps/main/components/chart/discover_chart.tsx rename to src/plugins/discover/public/application/main/components/chart/discover_chart.tsx index 1fe149f3eb17d..1c382dbdf6b5a 100644 --- a/src/plugins/discover/public/application/apps/main/components/chart/discover_chart.tsx +++ b/src/plugins/discover/public/application/main/components/chart/discover_chart.tsx @@ -17,14 +17,14 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { HitsCounter } from '../hits_counter'; -import { SavedSearch } from '../../../../../saved_searches'; +import { SavedSearch } from '../../../../services/saved_searches'; import { AppState, GetStateReturn } from '../../services/discover_state'; import { DiscoverHistogram } from './histogram'; -import { DataCharts$, DataTotalHits$ } from '../../services/use_saved_search'; -import { DiscoverServices } from '../../../../../build_services'; +import { DataCharts$, DataTotalHits$ } from '../../utils/use_saved_search'; +import { DiscoverServices } from '../../../../build_services'; import { useChartPanels } from './use_chart_panels'; -import { VIEW_MODE, DocumentViewModeToggle } from '../view_mode_toggle'; -import { SHOW_FIELD_STATISTICS } from '../../../../../../common'; +import { VIEW_MODE, DocumentViewModeToggle } from '../../../../components/view_mode_toggle'; +import { SHOW_FIELD_STATISTICS } from '../../../../../common'; const DiscoverHistogramMemoized = memo(DiscoverHistogram); export const CHART_HIDDEN_KEY = 'discover:chartHidden'; diff --git a/src/plugins/discover/public/application/apps/main/components/chart/histogram.scss b/src/plugins/discover/public/application/main/components/chart/histogram.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/chart/histogram.scss rename to src/plugins/discover/public/application/main/components/chart/histogram.scss diff --git a/src/plugins/discover/public/application/apps/main/components/chart/histogram.tsx b/src/plugins/discover/public/application/main/components/chart/histogram.tsx similarity index 96% rename from src/plugins/discover/public/application/apps/main/components/chart/histogram.tsx rename to src/plugins/discover/public/application/main/components/chart/histogram.tsx index 315ab7bad40f1..9bdf9dd61e703 100644 --- a/src/plugins/discover/public/application/apps/main/components/chart/histogram.tsx +++ b/src/plugins/discover/public/application/main/components/chart/histogram.tsx @@ -38,12 +38,12 @@ import { Endzones, getAdjustedInterval, renderEndzoneTooltip, -} from '../../../../../../../charts/public'; -import { DataCharts$, DataChartsMessage } from '../../services/use_saved_search'; -import { FetchStatus } from '../../../../types'; -import { DiscoverServices } from '../../../../../build_services'; +} from '../../../../../../charts/public'; +import { DataCharts$, DataChartsMessage } from '../../utils/use_saved_search'; +import { FetchStatus } from '../../../types'; +import { DiscoverServices } from '../../../../build_services'; import { useDataState } from '../../utils/use_data_state'; -import { LEGACY_TIME_AXIS, MULTILAYER_TIME_AXIS_STYLE } from '../../../../../../../charts/common'; +import { LEGACY_TIME_AXIS, MULTILAYER_TIME_AXIS_STYLE } from '../../../../../../charts/common'; export interface DiscoverHistogramProps { savedSearchData$: DataCharts$; diff --git a/src/plugins/discover/public/application/apps/main/components/chart/index.ts b/src/plugins/discover/public/application/main/components/chart/index.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/chart/index.ts rename to src/plugins/discover/public/application/main/components/chart/index.ts diff --git a/src/plugins/discover/public/application/apps/main/components/chart/point_series.test.ts b/src/plugins/discover/public/application/main/components/chart/point_series.test.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/chart/point_series.test.ts rename to src/plugins/discover/public/application/main/components/chart/point_series.test.ts diff --git a/src/plugins/discover/public/application/apps/main/components/chart/point_series.ts b/src/plugins/discover/public/application/main/components/chart/point_series.ts similarity index 96% rename from src/plugins/discover/public/application/apps/main/components/chart/point_series.ts rename to src/plugins/discover/public/application/main/components/chart/point_series.ts index ee057fcb48c6a..b8cdf75d5fd36 100644 --- a/src/plugins/discover/public/application/apps/main/components/chart/point_series.ts +++ b/src/plugins/discover/public/application/main/components/chart/point_series.ts @@ -9,7 +9,7 @@ import { uniq } from 'lodash'; import { Duration, Moment } from 'moment'; import { Unit } from '@elastic/datemath'; -import type { SerializedFieldFormat } from '../../../../../../../field_formats/common'; +import { SerializedFieldFormat } from '../../../../../../field_formats/common'; export interface Column { id: string; diff --git a/src/plugins/discover/public/application/apps/main/components/chart/use_chart_panels.test.ts b/src/plugins/discover/public/application/main/components/chart/use_chart_panels.test.ts similarity index 94% rename from src/plugins/discover/public/application/apps/main/components/chart/use_chart_panels.test.ts rename to src/plugins/discover/public/application/main/components/chart/use_chart_panels.test.ts index a1b9c30380969..20f19ec4719e9 100644 --- a/src/plugins/discover/public/application/apps/main/components/chart/use_chart_panels.test.ts +++ b/src/plugins/discover/public/application/main/components/chart/use_chart_panels.test.ts @@ -11,8 +11,8 @@ import { renderHook } from '@testing-library/react-hooks'; import { useChartPanels } from './use_chart_panels'; import { AppState } from '../../services/discover_state'; import { BehaviorSubject } from 'rxjs'; -import { DataCharts$ } from '../../services/use_saved_search'; -import { FetchStatus } from '../../../../types'; +import { DataCharts$ } from '../../utils/use_saved_search'; +import { FetchStatus } from '../../../types'; import { EuiContextMenuPanelDescriptor } from '@elastic/eui'; describe('test useChartPanels', () => { diff --git a/src/plugins/discover/public/application/apps/main/components/chart/use_chart_panels.ts b/src/plugins/discover/public/application/main/components/chart/use_chart_panels.ts similarity index 95% rename from src/plugins/discover/public/application/apps/main/components/chart/use_chart_panels.ts rename to src/plugins/discover/public/application/main/components/chart/use_chart_panels.ts index 3660173ef761d..cf09506c4f552 100644 --- a/src/plugins/discover/public/application/apps/main/components/chart/use_chart_panels.ts +++ b/src/plugins/discover/public/application/main/components/chart/use_chart_panels.ts @@ -10,9 +10,9 @@ import type { EuiContextMenuPanelItemDescriptor, EuiContextMenuPanelDescriptor, } from '@elastic/eui'; -import { search } from '../../../../../../../data/public'; +import { search } from '../../../../../../data/public'; import { AppState } from '../../services/discover_state'; -import { DataCharts$ } from '../../services/use_saved_search'; +import { DataCharts$ } from '../../utils/use_saved_search'; export function useChartPanels( state: AppState, diff --git a/src/plugins/discover/public/application/apps/main/components/hits_counter/hits_counter.scss b/src/plugins/discover/public/application/main/components/hits_counter/hits_counter.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/hits_counter/hits_counter.scss rename to src/plugins/discover/public/application/main/components/hits_counter/hits_counter.scss diff --git a/src/plugins/discover/public/application/apps/main/components/hits_counter/hits_counter.test.tsx b/src/plugins/discover/public/application/main/components/hits_counter/hits_counter.test.tsx similarity index 95% rename from src/plugins/discover/public/application/apps/main/components/hits_counter/hits_counter.test.tsx rename to src/plugins/discover/public/application/main/components/hits_counter/hits_counter.test.tsx index 02644fbf507dd..d46600fca01f4 100644 --- a/src/plugins/discover/public/application/apps/main/components/hits_counter/hits_counter.test.tsx +++ b/src/plugins/discover/public/application/main/components/hits_counter/hits_counter.test.tsx @@ -12,8 +12,8 @@ import { ReactWrapper } from 'enzyme'; import { HitsCounter, HitsCounterProps } from './hits_counter'; import { findTestSubject } from '@elastic/eui/lib/test'; import { BehaviorSubject } from 'rxjs'; -import { FetchStatus } from '../../../../types'; -import { DataTotalHits$ } from '../../services/use_saved_search'; +import { FetchStatus } from '../../../types'; +import { DataTotalHits$ } from '../../utils/use_saved_search'; describe('hits counter', function () { let props: HitsCounterProps; diff --git a/src/plugins/discover/public/application/apps/main/components/hits_counter/hits_counter.tsx b/src/plugins/discover/public/application/main/components/hits_counter/hits_counter.tsx similarity index 96% rename from src/plugins/discover/public/application/apps/main/components/hits_counter/hits_counter.tsx rename to src/plugins/discover/public/application/main/components/hits_counter/hits_counter.tsx index ab6617cbe79de..47c50f7bd47f5 100644 --- a/src/plugins/discover/public/application/apps/main/components/hits_counter/hits_counter.tsx +++ b/src/plugins/discover/public/application/main/components/hits_counter/hits_counter.tsx @@ -17,8 +17,8 @@ import { } from '@elastic/eui'; import { FormattedMessage, FormattedNumber } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { DataTotalHits$, DataTotalHitsMsg } from '../../services/use_saved_search'; -import { FetchStatus } from '../../../../types'; +import { DataTotalHits$, DataTotalHitsMsg } from '../../utils/use_saved_search'; +import { FetchStatus } from '../../../types'; import { useDataState } from '../../utils/use_data_state'; export interface HitsCounterProps { diff --git a/src/plugins/discover/public/application/apps/main/components/hits_counter/index.ts b/src/plugins/discover/public/application/main/components/hits_counter/index.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/hits_counter/index.ts rename to src/plugins/discover/public/application/main/components/hits_counter/index.ts diff --git a/src/plugins/discover/public/application/apps/main/components/layout/discover_documents.test.tsx b/src/plugins/discover/public/application/main/components/layout/discover_documents.test.tsx similarity index 75% rename from src/plugins/discover/public/application/apps/main/components/layout/discover_documents.test.tsx rename to src/plugins/discover/public/application/main/components/layout/discover_documents.test.tsx index 60540268dcd7f..829d88bbafd08 100644 --- a/src/plugins/discover/public/application/apps/main/components/layout/discover_documents.test.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_documents.test.tsx @@ -9,20 +9,20 @@ import React from 'react'; import { BehaviorSubject } from 'rxjs'; import { mountWithIntl } from '@kbn/test/jest'; -import { setHeaderActionMenuMounter } from '../../../../../kibana_services'; -import { esHits } from '../../../../../__mocks__/es_hits'; -import { savedSearchMock } from '../../../../../__mocks__/saved_search'; +import { setHeaderActionMenuMounter } from '../../../../kibana_services'; +import { esHits } from '../../../../__mocks__/es_hits'; +import { savedSearchMock } from '../../../../__mocks__/saved_search'; import { GetStateReturn } from '../../services/discover_state'; -import { DataDocuments$ } from '../../services/use_saved_search'; -import { discoverServiceMock } from '../../../../../__mocks__/services'; -import { FetchStatus } from '../../../../types'; +import { DataDocuments$ } from '../../utils/use_saved_search'; +import { discoverServiceMock } from '../../../../__mocks__/services'; +import { FetchStatus } from '../../../types'; import { DiscoverDocuments } from './discover_documents'; -import { ElasticSearchHit } from '../../../../doc_views/doc_views_types'; -import { indexPatternMock } from '../../../../../__mocks__/index_pattern'; +import { ElasticSearchHit } from '../../../../services/doc_views/doc_views_types'; +import { indexPatternMock } from '../../../../__mocks__/index_pattern'; -jest.mock('../../../../../kibana_services', () => ({ - ...jest.requireActual('../../../../../kibana_services'), - getServices: () => jest.requireActual('../../../../../__mocks__/services').discoverServiceMock, +jest.mock('../../../../kibana_services', () => ({ + ...jest.requireActual('../../../../kibana_services'), + getServices: () => jest.requireActual('../../../../__mocks__/services').discoverServiceMock, })); setHeaderActionMenuMounter(jest.fn()); diff --git a/src/plugins/discover/public/application/apps/main/components/layout/discover_documents.tsx b/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx similarity index 88% rename from src/plugins/discover/public/application/apps/main/components/layout/discover_documents.tsx rename to src/plugins/discover/public/application/main/components/layout/discover_documents.tsx index 64d5e08f25d73..08582b21a90ac 100644 --- a/src/plugins/discover/public/application/apps/main/components/layout/discover_documents.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx @@ -14,24 +14,24 @@ import { EuiScreenReaderOnly, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { DocViewFilterFn, ElasticSearchHit } from '../../../../doc_views/doc_views_types'; +import { DocViewFilterFn, ElasticSearchHit } from '../../../../services/doc_views/doc_views_types'; import { DiscoverGrid } from '../../../../components/discover_grid/discover_grid'; -import { FetchStatus } from '../../../../types'; +import { FetchStatus } from '../../../types'; import { DOC_HIDE_TIME_COLUMN_SETTING, DOC_TABLE_LEGACY, SAMPLE_SIZE_SETTING, SEARCH_FIELDS_FROM_SOURCE, -} from '../../../../../../common'; -import { useColumns } from '../../../../helpers/use_data_grid_columns'; -import { IndexPattern } from '../../../../../../../data/common'; -import { SavedSearch } from '../../../../../saved_searches'; -import { DataDocumentsMsg, DataDocuments$ } from '../../services/use_saved_search'; -import { DiscoverServices } from '../../../../../build_services'; +} from '../../../../../common'; +import { useColumns } from '../../../../utils/use_data_grid_columns'; +import { IndexPattern } from '../../../../../../data/common'; +import { SavedSearch } from '../../../../services/saved_searches'; +import { DataDocumentsMsg, DataDocuments$ } from '../../utils/use_saved_search'; +import { DiscoverServices } from '../../../../build_services'; import { AppState, GetStateReturn } from '../../services/discover_state'; import { useDataState } from '../../utils/use_data_state'; -import { DocTableInfinite } from '../doc_table/doc_table_infinite'; -import { SortPairArr } from '../doc_table/lib/get_sort'; +import { DocTableInfinite } from '../../../../components/doc_table/doc_table_infinite'; +import { SortPairArr } from '../../../../components/doc_table/lib/get_sort'; const DocTableInfiniteMemoized = React.memo(DocTableInfinite); const DataGridMemoized = React.memo(DiscoverGrid); diff --git a/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.scss b/src/plugins/discover/public/application/main/components/layout/discover_layout.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/layout/discover_layout.scss rename to src/plugins/discover/public/application/main/components/layout/discover_layout.scss diff --git a/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.test.tsx b/src/plugins/discover/public/application/main/components/layout/discover_layout.test.tsx similarity index 85% rename from src/plugins/discover/public/application/apps/main/components/layout/discover_layout.test.tsx rename to src/plugins/discover/public/application/main/components/layout/discover_layout.test.tsx index 7e3252dce1ef5..c222e4038f517 100644 --- a/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.test.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_layout.test.tsx @@ -9,15 +9,15 @@ import React from 'react'; import { Subject, BehaviorSubject } from 'rxjs'; import { mountWithIntl } from '@kbn/test/jest'; -import { setHeaderActionMenuMounter } from '../../../../../kibana_services'; +import { setHeaderActionMenuMounter } from '../../../../kibana_services'; import { DiscoverLayout, SIDEBAR_CLOSED_KEY } from './discover_layout'; -import { esHits } from '../../../../../__mocks__/es_hits'; -import { indexPatternMock } from '../../../../../__mocks__/index_pattern'; -import { savedSearchMock } from '../../../../../__mocks__/saved_search'; -import { createSearchSourceMock } from '../../../../../../../data/common/search/search_source/mocks'; -import { IndexPattern, IndexPatternAttributes } from '../../../../../../../data/common'; -import { SavedObject } from '../../../../../../../../core/types'; -import { indexPatternWithTimefieldMock } from '../../../../../__mocks__/index_pattern_with_timefield'; +import { esHits } from '../../../../__mocks__/es_hits'; +import { indexPatternMock } from '../../../../__mocks__/index_pattern'; +import { savedSearchMock } from '../../../../__mocks__/saved_search'; +import { createSearchSourceMock } from '../../../../../../data/common/search/search_source/mocks'; +import { IndexPattern, IndexPatternAttributes } from '../../../../../../data/common'; +import { SavedObject } from '../../../../../../../core/types'; +import { indexPatternWithTimefieldMock } from '../../../../__mocks__/index_pattern_with_timefield'; import { GetStateReturn } from '../../services/discover_state'; import { DiscoverLayoutProps } from './types'; import { @@ -25,16 +25,16 @@ import { DataDocuments$, DataMain$, DataTotalHits$, -} from '../../services/use_saved_search'; -import { discoverServiceMock } from '../../../../../__mocks__/services'; -import { FetchStatus } from '../../../../types'; -import { ElasticSearchHit } from '../../../../doc_views/doc_views_types'; -import { RequestAdapter } from '../../../../../../../inspector'; +} from '../../utils/use_saved_search'; +import { discoverServiceMock } from '../../../../__mocks__/services'; +import { FetchStatus } from '../../../types'; +import { ElasticSearchHit } from '../../../../services/doc_views/doc_views_types'; +import { RequestAdapter } from '../../../../../../inspector'; import { Chart } from '../chart/point_series'; import { DiscoverSidebar } from '../sidebar/discover_sidebar'; -jest.mock('../../../../../kibana_services', () => ({ - ...jest.requireActual('../../../../../kibana_services'), +jest.mock('../../../../kibana_services', () => ({ + ...jest.requireActual('../../../../kibana_services'), getServices: () => ({ fieldFormats: { getDefaultInstance: jest.fn(() => ({ convert: (value: unknown) => value })), diff --git a/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx b/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx similarity index 95% rename from src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx rename to src/plugins/discover/public/application/main/components/layout/discover_layout.tsx index 76ed7069b294a..115b9eb1a63bf 100644 --- a/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx @@ -23,28 +23,28 @@ import { METRIC_TYPE } from '@kbn/analytics'; import classNames from 'classnames'; import { DiscoverNoResults } from '../no_results'; import { LoadingSpinner } from '../loading_spinner/loading_spinner'; -import { esFilters, IndexPatternField } from '../../../../../../../data/public'; +import { esFilters, IndexPatternField } from '../../../../../../data/public'; import { DiscoverSidebarResponsive } from '../sidebar'; import { DiscoverLayoutProps } from './types'; -import { SEARCH_FIELDS_FROM_SOURCE, SHOW_FIELD_STATISTICS } from '../../../../../../common'; -import { popularizeField } from '../../../../helpers/popularize_field'; +import { SEARCH_FIELDS_FROM_SOURCE, SHOW_FIELD_STATISTICS } from '../../../../../common'; +import { popularizeField } from '../../../../utils/popularize_field'; import { DiscoverTopNav } from '../top_nav/discover_topnav'; -import { DocViewFilterFn, ElasticSearchHit } from '../../../../doc_views/doc_views_types'; +import { DocViewFilterFn, ElasticSearchHit } from '../../../../services/doc_views/doc_views_types'; import { DiscoverChart } from '../chart'; import { getResultState } from '../../utils/get_result_state'; -import { InspectorSession } from '../../../../../../../inspector/public'; +import { InspectorSession } from '../../../../../../inspector/public'; import { DiscoverUninitialized } from '../uninitialized/uninitialized'; -import { DataMainMsg } from '../../services/use_saved_search'; -import { useColumns } from '../../../../helpers/use_data_grid_columns'; +import { DataMainMsg } from '../../utils/use_saved_search'; +import { useColumns } from '../../../../utils/use_data_grid_columns'; import { DiscoverDocuments } from './discover_documents'; -import { FetchStatus } from '../../../../types'; +import { FetchStatus } from '../../../types'; import { useDataState } from '../../utils/use_data_state'; import { SavedSearchURLConflictCallout, useSavedSearchAliasMatchRedirect, -} from '../../../../../saved_searches'; +} from '../../../../services/saved_searches'; import { DiscoverDataVisualizerGrid } from '../../../../components/data_visualizer_grid'; -import { VIEW_MODE } from '../view_mode_toggle'; +import { VIEW_MODE } from '../../../../components/view_mode_toggle'; /** * Local storage key for sidebar persistence state diff --git a/src/plugins/discover/public/application/apps/main/components/layout/index.ts b/src/plugins/discover/public/application/main/components/layout/index.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/layout/index.ts rename to src/plugins/discover/public/application/main/components/layout/index.ts diff --git a/src/plugins/discover/public/application/apps/main/components/layout/types.ts b/src/plugins/discover/public/application/main/components/layout/types.ts similarity index 74% rename from src/plugins/discover/public/application/apps/main/components/layout/types.ts rename to src/plugins/discover/public/application/main/components/layout/types.ts index e4a780cadceae..1ed34978416fa 100644 --- a/src/plugins/discover/public/application/apps/main/components/layout/types.ts +++ b/src/plugins/discover/public/application/main/components/layout/types.ts @@ -12,13 +12,13 @@ import { Query, SavedObject, TimeRange, -} from '../../../../../../../data/common'; -import { ISearchSource } from '../../../../../../../data/public'; +} from '../../../../../../data/common'; +import { ISearchSource } from '../../../../../../data/public'; import { AppState, GetStateReturn } from '../../services/discover_state'; -import { DataRefetch$, SavedSearchData } from '../../services/use_saved_search'; -import { DiscoverServices } from '../../../../../build_services'; -import { SavedSearch } from '../../../../../saved_searches'; -import { RequestAdapter } from '../../../../../../../inspector'; +import { DataRefetch$, SavedSearchData } from '../../utils/use_saved_search'; +import { DiscoverServices } from '../../../../build_services'; +import { SavedSearch } from '../../../../services/saved_searches'; +import { RequestAdapter } from '../../../../../../inspector'; export interface DiscoverLayoutProps { indexPattern: IndexPattern; diff --git a/src/plugins/discover/public/application/apps/main/components/loading_spinner/loading_spinner.scss b/src/plugins/discover/public/application/main/components/loading_spinner/loading_spinner.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/loading_spinner/loading_spinner.scss rename to src/plugins/discover/public/application/main/components/loading_spinner/loading_spinner.scss diff --git a/src/plugins/discover/public/application/apps/main/components/loading_spinner/loading_spinner.test.tsx b/src/plugins/discover/public/application/main/components/loading_spinner/loading_spinner.test.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/loading_spinner/loading_spinner.test.tsx rename to src/plugins/discover/public/application/main/components/loading_spinner/loading_spinner.test.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/loading_spinner/loading_spinner.tsx b/src/plugins/discover/public/application/main/components/loading_spinner/loading_spinner.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/loading_spinner/loading_spinner.tsx rename to src/plugins/discover/public/application/main/components/loading_spinner/loading_spinner.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/no_results/_no_results.scss b/src/plugins/discover/public/application/main/components/no_results/_no_results.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/no_results/_no_results.scss rename to src/plugins/discover/public/application/main/components/no_results/_no_results.scss diff --git a/src/plugins/discover/public/application/apps/main/components/no_results/assets/no_results_illustration.scss b/src/plugins/discover/public/application/main/components/no_results/assets/no_results_illustration.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/no_results/assets/no_results_illustration.scss rename to src/plugins/discover/public/application/main/components/no_results/assets/no_results_illustration.scss diff --git a/src/plugins/discover/public/application/apps/main/components/no_results/assets/no_results_illustration.tsx b/src/plugins/discover/public/application/main/components/no_results/assets/no_results_illustration.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/no_results/assets/no_results_illustration.tsx rename to src/plugins/discover/public/application/main/components/no_results/assets/no_results_illustration.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/no_results/index.ts b/src/plugins/discover/public/application/main/components/no_results/index.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/no_results/index.ts rename to src/plugins/discover/public/application/main/components/no_results/index.ts diff --git a/src/plugins/discover/public/application/apps/main/components/no_results/no_results.test.tsx b/src/plugins/discover/public/application/main/components/no_results/no_results.test.tsx similarity index 98% rename from src/plugins/discover/public/application/apps/main/components/no_results/no_results.test.tsx rename to src/plugins/discover/public/application/main/components/no_results/no_results.test.tsx index 3a42a22d1d2eb..1f6a2235b916f 100644 --- a/src/plugins/discover/public/application/apps/main/components/no_results/no_results.test.tsx +++ b/src/plugins/discover/public/application/main/components/no_results/no_results.test.tsx @@ -12,7 +12,7 @@ import { findTestSubject } from '@elastic/eui/lib/test'; import { DiscoverNoResults, DiscoverNoResultsProps } from './no_results'; -jest.mock('../../../../../kibana_services', () => { +jest.mock('../../../../kibana_services', () => { return { getServices: () => ({ docLinks: { diff --git a/src/plugins/discover/public/application/apps/main/components/no_results/no_results.tsx b/src/plugins/discover/public/application/main/components/no_results/no_results.tsx similarity index 97% rename from src/plugins/discover/public/application/apps/main/components/no_results/no_results.tsx rename to src/plugins/discover/public/application/main/components/no_results/no_results.tsx index 852c0860fd0c1..38dce654f0daa 100644 --- a/src/plugins/discover/public/application/apps/main/components/no_results/no_results.tsx +++ b/src/plugins/discover/public/application/main/components/no_results/no_results.tsx @@ -16,7 +16,7 @@ import { EuiSpacer, EuiTitle, } from '@elastic/eui'; -import { DataPublicPluginStart } from '../../../../../../../data/public'; +import { DataPublicPluginStart } from '../../../../../../data/public'; import { AdjustSearch, getTimeFieldMessage } from './no_results_helper'; import './_no_results.scss'; import { NoResultsIllustration } from './assets/no_results_illustration'; diff --git a/src/plugins/discover/public/application/apps/main/components/no_results/no_results_helper.tsx b/src/plugins/discover/public/application/main/components/no_results/no_results_helper.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/no_results/no_results_helper.tsx rename to src/plugins/discover/public/application/main/components/no_results/no_results_helper.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/__snapshots__/discover_index_pattern.test.tsx.snap b/src/plugins/discover/public/application/main/components/sidebar/__snapshots__/discover_index_pattern.test.tsx.snap similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/sidebar/__snapshots__/discover_index_pattern.test.tsx.snap rename to src/plugins/discover/public/application/main/components/sidebar/__snapshots__/discover_index_pattern.test.tsx.snap diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/__snapshots__/discover_index_pattern_management.test.tsx.snap b/src/plugins/discover/public/application/main/components/sidebar/__snapshots__/discover_index_pattern_management.test.tsx.snap similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/sidebar/__snapshots__/discover_index_pattern_management.test.tsx.snap rename to src/plugins/discover/public/application/main/components/sidebar/__snapshots__/discover_index_pattern_management.test.tsx.snap diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/change_indexpattern.test.tsx b/src/plugins/discover/public/application/main/components/sidebar/change_indexpattern.test.tsx similarity index 93% rename from src/plugins/discover/public/application/apps/main/components/sidebar/change_indexpattern.test.tsx rename to src/plugins/discover/public/application/main/components/sidebar/change_indexpattern.test.tsx index 8c32942740a76..b61683c8de14a 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/change_indexpattern.test.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/change_indexpattern.test.tsx @@ -11,8 +11,8 @@ import { ShallowWrapper } from 'enzyme'; import { act } from 'react-dom/test-utils'; import { shallowWithIntl } from '@kbn/test/jest'; import { ChangeIndexPattern } from './change_indexpattern'; -import { indexPatternMock } from '../../../../../__mocks__/index_pattern'; -import { indexPatternWithTimefieldMock } from '../../../../../__mocks__/index_pattern_with_timefield'; +import { indexPatternMock } from '../../../../__mocks__/index_pattern'; +import { indexPatternWithTimefieldMock } from '../../../../__mocks__/index_pattern_with_timefield'; import { IndexPatternRef } from './types'; function getProps() { diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/change_indexpattern.tsx b/src/plugins/discover/public/application/main/components/sidebar/change_indexpattern.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/sidebar/change_indexpattern.tsx rename to src/plugins/discover/public/application/main/components/sidebar/change_indexpattern.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field.scss b/src/plugins/discover/public/application/main/components/sidebar/discover_field.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_field.scss rename to src/plugins/discover/public/application/main/components/sidebar/discover_field.scss diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field.test.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_field.test.tsx similarity index 95% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_field.test.tsx rename to src/plugins/discover/public/application/main/components/sidebar/discover_field.test.tsx index 1dfc14d6c20b9..fbbe68a43f5e5 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field.test.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_field.test.tsx @@ -11,10 +11,10 @@ import { findTestSubject } from '@elastic/eui/lib/test'; import { mountWithIntl } from '@kbn/test/jest'; import { DiscoverField } from './discover_field'; -import { IndexPatternField } from '../../../../../../../data/public'; -import { stubIndexPattern } from '../../../../../../../data/common/stubs'; +import { IndexPatternField } from '../../../../../../data/public'; +import { stubIndexPattern } from '../../../../../../data/common/stubs'; -jest.mock('../../../../../kibana_services', () => ({ +jest.mock('../../../../kibana_services', () => ({ getUiActions: jest.fn(() => { return { getTriggerCompatibleActions: jest.fn(() => []), diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_field.tsx similarity index 99% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_field.tsx rename to src/plugins/discover/public/application/main/components/sidebar/discover_field.tsx index 89e7b50187630..c254f5531a8f0 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_field.tsx @@ -25,9 +25,9 @@ import { i18n } from '@kbn/i18n'; import { UiCounterMetricType } from '@kbn/analytics'; import classNames from 'classnames'; import { DiscoverFieldDetails } from './discover_field_details'; -import { FieldIcon, FieldButton } from '../../../../../../../kibana_react/public'; +import { FieldIcon, FieldButton } from '../../../../../../kibana_react/public'; import { FieldDetails } from './types'; -import { IndexPatternField, IndexPattern } from '../../../../../../../data/public'; +import { IndexPatternField, IndexPattern } from '../../../../../../data/public'; import { getFieldTypeName } from './lib/get_field_type_name'; import { DiscoverFieldVisualize } from './discover_field_visualize'; diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_bucket.scss b/src/plugins/discover/public/application/main/components/sidebar/discover_field_bucket.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_bucket.scss rename to src/plugins/discover/public/application/main/components/sidebar/discover_field_bucket.scss diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_bucket.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_field_bucket.tsx similarity index 98% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_bucket.tsx rename to src/plugins/discover/public/application/main/components/sidebar/discover_field_bucket.tsx index 7dab8cecf28a9..9b0134bf19406 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_bucket.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_field_bucket.tsx @@ -11,7 +11,7 @@ import { EuiText, EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@e import { i18n } from '@kbn/i18n'; import { StringFieldProgressBar } from './string_progress_bar'; import { Bucket } from './types'; -import { IndexPatternField } from '../../../../../../../data/public'; +import { IndexPatternField } from '../../../../../../data/public'; import './discover_field_bucket.scss'; interface Props { diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_details.test.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_field_details.test.tsx similarity index 91% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_details.test.tsx rename to src/plugins/discover/public/application/main/components/sidebar/discover_field_details.test.tsx index f873cfa2151da..fb3f34b1eff26 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_details.test.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_field_details.test.tsx @@ -11,8 +11,8 @@ import { findTestSubject } from '@elastic/eui/lib/test'; import { mountWithIntl } from '@kbn/test/jest'; import { DiscoverFieldDetails } from './discover_field_details'; -import { IndexPatternField } from '../../../../../../../data/public'; -import { stubIndexPattern } from '../../../../../../../data/common/stubs'; +import { IndexPatternField } from '../../../../../../data/public'; +import { stubIndexPattern } from '../../../../../../data/common/stubs'; describe('discover sidebar field details', function () { const onAddFilter = jest.fn(); diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_details.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_field_details.tsx similarity index 99% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_details.tsx rename to src/plugins/discover/public/application/main/components/sidebar/discover_field_details.tsx index e29799b720e21..af2a322d97806 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_details.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_field_details.tsx @@ -11,7 +11,7 @@ import { EuiText, EuiSpacer, EuiLink } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { DiscoverFieldBucket } from './discover_field_bucket'; import { Bucket, FieldDetails } from './types'; -import { IndexPatternField, IndexPattern } from '../../../../../../../data/public'; +import { IndexPatternField, IndexPattern } from '../../../../../../data/public'; interface DiscoverFieldDetailsProps { field: IndexPatternField; diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_search.scss b/src/plugins/discover/public/application/main/components/sidebar/discover_field_search.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_search.scss rename to src/plugins/discover/public/application/main/components/sidebar/discover_field_search.scss diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_search.test.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_field_search.test.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_search.test.tsx rename to src/plugins/discover/public/application/main/components/sidebar/discover_field_search.test.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_search.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_field_search.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_search.tsx rename to src/plugins/discover/public/application/main/components/sidebar/discover_field_search.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_visualize.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_field_visualize.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_visualize.tsx rename to src/plugins/discover/public/application/main/components/sidebar/discover_field_visualize.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.test.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_index_pattern.test.tsx similarity index 97% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.test.tsx rename to src/plugins/discover/public/application/main/components/sidebar/discover_index_pattern.test.tsx index 50af66511de30..4f1f26f2794a4 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.test.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_index_pattern.test.tsx @@ -15,7 +15,7 @@ import { SavedObject } from 'kibana/server'; import { DiscoverIndexPattern, DiscoverIndexPatternProps } from './discover_index_pattern'; import { EuiSelectable } from '@elastic/eui'; import { IndexPattern, IndexPatternAttributes } from 'src/plugins/data/public'; -import { indexPatternsMock } from '../../../../../__mocks__/index_patterns'; +import { indexPatternsMock } from '../../../../__mocks__/index_patterns'; const indexPattern = { id: 'the-index-pattern-id-first', diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_index_pattern.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx rename to src/plugins/discover/public/application/main/components/sidebar/discover_index_pattern.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern_management.test.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_index_pattern_management.test.tsx similarity index 92% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern_management.test.tsx rename to src/plugins/discover/public/application/main/components/sidebar/discover_index_pattern_management.test.tsx index 4e41c457ab8eb..c5b1f4d2612d6 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern_management.test.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_index_pattern_management.test.tsx @@ -7,12 +7,11 @@ */ import React from 'react'; -import { mountWithIntl } from '@kbn/test/jest'; +import { mountWithIntl, findTestSubject } from '@kbn/test/jest'; import { EuiContextMenuPanel, EuiPopover, EuiContextMenuItem } from '@elastic/eui'; -import { findTestSubject } from '@kbn/test/jest'; -import { DiscoverServices } from '../../../../../build_services'; +import { DiscoverServices } from '../../../../build_services'; import { DiscoverIndexPatternManagement } from './discover_index_pattern_management'; -import { stubLogstashIndexPattern } from '../../../../../../../data/common/stubs'; +import { stubLogstashIndexPattern } from '../../../../../../data/common/stubs'; const mockServices = { history: () => ({ diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern_management.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_index_pattern_management.tsx similarity index 96% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern_management.tsx rename to src/plugins/discover/public/application/main/components/sidebar/discover_index_pattern_management.tsx index 81e9f821ca6c0..9353073e7fad6 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern_management.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_index_pattern_management.tsx @@ -9,8 +9,8 @@ import React, { useState } from 'react'; import { EuiButtonIcon, EuiContextMenuItem, EuiContextMenuPanel, EuiPopover } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { DiscoverServices } from '../../../../../build_services'; -import { IndexPattern } from '../../../../../../../data/common'; +import { DiscoverServices } from '../../../../build_services'; +import { IndexPattern } from '../../../../../../data/common'; export interface DiscoverIndexPatternManagementProps { /** diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar.scss b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar.scss rename to src/plugins/discover/public/application/main/components/sidebar/discover_sidebar.scss diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar.test.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar.test.tsx similarity index 88% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar.test.tsx rename to src/plugins/discover/public/application/main/components/sidebar/discover_sidebar.test.tsx index 03616c136df3e..b2b5c8a056995 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar.test.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar.test.tsx @@ -10,21 +10,21 @@ import { each, cloneDeep } from 'lodash'; import { ReactWrapper } from 'enzyme'; import { findTestSubject } from '@elastic/eui/lib/test'; // @ts-expect-error -import realHits from '../../../../../__fixtures__/real_hits.js'; +import realHits from '../../../../__fixtures__/real_hits.js'; import { mountWithIntl } from '@kbn/test/jest'; import React from 'react'; import { DiscoverSidebarProps } from './discover_sidebar'; -import { flattenHit, IndexPatternAttributes } from '../../../../../../../data/common'; -import { SavedObject } from '../../../../../../../../core/types'; +import { flattenHit, IndexPatternAttributes } from '../../../../../../data/common'; +import { SavedObject } from '../../../../../../../core/types'; import { getDefaultFieldFilter } from './lib/field_filter'; import { DiscoverSidebarComponent as DiscoverSidebar } from './discover_sidebar'; -import { ElasticSearchHit } from '../../../../doc_views/doc_views_types'; -import { discoverServiceMock as mockDiscoverServices } from '../../../../../__mocks__/services'; -import { stubLogstashIndexPattern } from '../../../../../../../data/common/stubs'; -import { VIEW_MODE } from '../view_mode_toggle'; +import { ElasticSearchHit } from '../../../../services/doc_views/doc_views_types'; +import { discoverServiceMock as mockDiscoverServices } from '../../../../__mocks__/services'; +import { stubLogstashIndexPattern } from '../../../../../../data/common/stubs'; +import { VIEW_MODE } from '../../../../components/view_mode_toggle'; -jest.mock('../../../../../kibana_services', () => ({ +jest.mock('../../../../kibana_services', () => ({ getServices: () => mockDiscoverServices, })); diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar.tsx similarity index 98% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar.tsx rename to src/plugins/discover/public/application/main/components/sidebar/discover_sidebar.tsx index d13860eab0d24..fcc4d32151018 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar.tsx @@ -28,19 +28,19 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { DiscoverField } from './discover_field'; import { DiscoverIndexPattern } from './discover_index_pattern'; import { DiscoverFieldSearch } from './discover_field_search'; -import { FIELDS_LIMIT_SETTING } from '../../../../../../common'; +import { FIELDS_LIMIT_SETTING } from '../../../../../common'; import { groupFields } from './lib/group_fields'; import { IndexPatternField, indexPatterns as indexPatternUtils, -} from '../../../../../../../data/public'; +} from '../../../../../../data/public'; import { getDetails } from './lib/get_details'; import { FieldFilterState, getDefaultFieldFilter, setFieldFilterProp } from './lib/field_filter'; import { getIndexPatternFieldList } from './lib/get_index_pattern_field_list'; import { DiscoverSidebarResponsiveProps } from './discover_sidebar_responsive'; import { DiscoverIndexPatternManagement } from './discover_index_pattern_management'; -import { ElasticSearchHit } from '../../../../doc_views/doc_views_types'; -import { VIEW_MODE } from '../view_mode_toggle'; +import { ElasticSearchHit } from '../../../../services/doc_views/doc_views_types'; +import { VIEW_MODE } from '../../../../components/view_mode_toggle'; /** * Default number of available fields displayed and added on scroll diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.test.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.test.tsx similarity index 88% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.test.tsx rename to src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.test.tsx index 4e4fed8c65bf7..b412cd69c82af 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.test.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.test.tsx @@ -11,22 +11,22 @@ import { BehaviorSubject } from 'rxjs'; import { ReactWrapper } from 'enzyme'; import { findTestSubject } from '@elastic/eui/lib/test'; // @ts-expect-error -import realHits from '../../../../../__fixtures__/real_hits.js'; +import realHits from '../../../../__fixtures__/real_hits.js'; import { act } from 'react-dom/test-utils'; import { mountWithIntl } from '@kbn/test/jest'; import React from 'react'; -import { flattenHit, IndexPatternAttributes } from '../../../../../../../data/common'; -import { SavedObject } from '../../../../../../../../core/types'; +import { flattenHit, IndexPatternAttributes } from '../../../../../../data/common'; +import { SavedObject } from '../../../../../../../core/types'; import { DiscoverSidebarResponsive, DiscoverSidebarResponsiveProps, } from './discover_sidebar_responsive'; -import { DiscoverServices } from '../../../../../build_services'; -import { ElasticSearchHit } from '../../../../doc_views/doc_views_types'; -import { FetchStatus } from '../../../../types'; -import { DataDocuments$ } from '../../services/use_saved_search'; -import { stubLogstashIndexPattern } from '../../../../../../../data/common/stubs'; -import { VIEW_MODE } from '../view_mode_toggle'; +import { DiscoverServices } from '../../../../build_services'; +import { ElasticSearchHit } from '../../../../services/doc_views/doc_views_types'; +import { FetchStatus } from '../../../types'; +import { DataDocuments$ } from '../../utils/use_saved_search'; +import { stubLogstashIndexPattern } from '../../../../../../data/common/stubs'; +import { VIEW_MODE } from '../../../../components/view_mode_toggle'; const mockServices = { history: () => ({ @@ -56,7 +56,7 @@ const mockCalcFieldCounts = jest.fn(() => { return mockfieldCounts; }); -jest.mock('../../../../../kibana_services', () => ({ +jest.mock('../../../../kibana_services', () => ({ getUiActions: jest.fn(() => { return { getTriggerCompatibleActions: jest.fn(() => []), diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx similarity index 96% rename from src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx rename to src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx index 368a2b2e92d34..1df3044b81bf8 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx @@ -27,17 +27,17 @@ import { EuiFlexItem, } from '@elastic/eui'; import { DiscoverIndexPattern } from './discover_index_pattern'; -import { IndexPatternAttributes } from '../../../../../../../data/common'; -import { SavedObject } from '../../../../../../../../core/types'; -import { IndexPatternField, IndexPattern } from '../../../../../../../data/public'; +import { IndexPatternAttributes } from '../../../../../../data/common'; +import { SavedObject } from '../../../../../../../core/types'; +import { IndexPatternField, IndexPattern } from '../../../../../../data/public'; import { getDefaultFieldFilter } from './lib/field_filter'; import { DiscoverSidebar } from './discover_sidebar'; -import { DiscoverServices } from '../../../../../build_services'; +import { DiscoverServices } from '../../../../build_services'; import { AppState } from '../../services/discover_state'; import { DiscoverIndexPatternManagement } from './discover_index_pattern_management'; -import { DataDocuments$ } from '../../services/use_saved_search'; +import { DataDocuments$ } from '../../utils/use_saved_search'; import { calcFieldCounts } from '../../utils/calc_field_counts'; -import { VIEW_MODE } from '../view_mode_toggle'; +import { VIEW_MODE } from '../../../../components/view_mode_toggle'; export interface DiscoverSidebarResponsiveProps { /** diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/index.ts b/src/plugins/discover/public/application/main/components/sidebar/index.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/sidebar/index.ts rename to src/plugins/discover/public/application/main/components/sidebar/index.ts diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_calculator.js b/src/plugins/discover/public/application/main/components/sidebar/lib/field_calculator.js similarity index 98% rename from src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_calculator.js rename to src/plugins/discover/public/application/main/components/sidebar/lib/field_calculator.js index c709f3311105d..4f282f6133ef3 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_calculator.js +++ b/src/plugins/discover/public/application/main/components/sidebar/lib/field_calculator.js @@ -8,7 +8,7 @@ import { map, sortBy, without, each, defaults, isObject } from 'lodash'; import { i18n } from '@kbn/i18n'; -import { flattenHit } from '../../../../../../../../data/common'; +import { flattenHit } from '../../../../../../../data/common'; function getFieldValues(hits, field, indexPattern) { const name = field.name; diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_calculator.test.ts b/src/plugins/discover/public/application/main/components/sidebar/lib/field_calculator.test.ts similarity index 96% rename from src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_calculator.test.ts rename to src/plugins/discover/public/application/main/components/sidebar/lib/field_calculator.test.ts index d4bc41f36b2d4..519b298d70072 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_calculator.test.ts +++ b/src/plugins/discover/public/application/main/components/sidebar/lib/field_calculator.test.ts @@ -10,14 +10,14 @@ import { keys, each, cloneDeep, clone, uniq, filter, map } from 'lodash'; // @ts-expect-error -import realHits from '../../../../../../__fixtures__/real_hits.js'; +import realHits from '../../../../../__fixtures__/real_hits.js'; -import { IndexPattern } from '../../../../../../../../data/public'; -import { flattenHit } from '../../../../../../../../data/common'; +import { IndexPattern } from '../../../../../../../data/public'; +import { flattenHit } from '../../../../../../../data/common'; // @ts-expect-error import { fieldCalculator } from './field_calculator'; -import { stubLogstashIndexPattern as indexPattern } from '../../../../../../../../data/common/stubs'; +import { stubLogstashIndexPattern as indexPattern } from '../../../../../../../data/common/stubs'; describe('fieldCalculator', function () { it('should have a _countMissing that counts nulls & undefineds in an array', function () { diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_filter.test.ts b/src/plugins/discover/public/application/main/components/sidebar/lib/field_filter.test.ts similarity index 97% rename from src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_filter.test.ts rename to src/plugins/discover/public/application/main/components/sidebar/lib/field_filter.test.ts index 8d7c543157ead..23da318b6b1dd 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_filter.test.ts +++ b/src/plugins/discover/public/application/main/components/sidebar/lib/field_filter.test.ts @@ -7,7 +7,7 @@ */ import { getDefaultFieldFilter, setFieldFilterProp, isFieldFiltered } from './field_filter'; -import { IndexPatternField } from '../../../../../../../../data/public'; +import { IndexPatternField } from '../../../../../../../data/public'; describe('field_filter', function () { it('getDefaultFieldFilter should return default filter state', function () { diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_filter.ts b/src/plugins/discover/public/application/main/components/sidebar/lib/field_filter.ts similarity index 96% rename from src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_filter.ts rename to src/plugins/discover/public/application/main/components/sidebar/lib/field_filter.ts index 25a8309d3d963..9d685652be0a6 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/field_filter.ts +++ b/src/plugins/discover/public/application/main/components/sidebar/lib/field_filter.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { IndexPatternField } from '../../../../../../../../data/public'; +import { IndexPatternField } from '../../../../../../../data/public'; export interface FieldFilterState { missing: boolean; diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/get_details.ts b/src/plugins/discover/public/application/main/components/sidebar/lib/get_details.ts similarity index 90% rename from src/plugins/discover/public/application/apps/main/components/sidebar/lib/get_details.ts rename to src/plugins/discover/public/application/main/components/sidebar/lib/get_details.ts index cf7d9945a35e6..b5beebf6fb8d4 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/get_details.ts +++ b/src/plugins/discover/public/application/main/components/sidebar/lib/get_details.ts @@ -8,8 +8,8 @@ // @ts-expect-error import { fieldCalculator } from './field_calculator'; -import { IndexPattern, IndexPatternField } from '../../../../../../../../data/public'; -import { ElasticSearchHit } from '../../../../../doc_views/doc_views_types'; +import { IndexPattern, IndexPatternField } from '../../../../../../../data/public'; +import { ElasticSearchHit } from '../../../../../services/doc_views/doc_views_types'; export function getDetails( field: IndexPatternField, diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/get_field_type_name.ts b/src/plugins/discover/public/application/main/components/sidebar/lib/get_field_type_name.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/sidebar/lib/get_field_type_name.ts rename to src/plugins/discover/public/application/main/components/sidebar/lib/get_field_type_name.ts diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/get_index_pattern_field_list.ts b/src/plugins/discover/public/application/main/components/sidebar/lib/get_index_pattern_field_list.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/sidebar/lib/get_index_pattern_field_list.ts rename to src/plugins/discover/public/application/main/components/sidebar/lib/get_index_pattern_field_list.ts diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/group_fields.test.ts b/src/plugins/discover/public/application/main/components/sidebar/lib/group_fields.test.ts similarity index 98% rename from src/plugins/discover/public/application/apps/main/components/sidebar/lib/group_fields.test.ts rename to src/plugins/discover/public/application/main/components/sidebar/lib/group_fields.test.ts index 4842f652eb730..7e8eabd171d64 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/group_fields.test.ts +++ b/src/plugins/discover/public/application/main/components/sidebar/lib/group_fields.test.ts @@ -8,7 +8,7 @@ import { groupFields } from './group_fields'; import { getDefaultFieldFilter } from './field_filter'; -import { IndexPatternField } from '../../../../../../../../data/common'; +import { IndexPatternField } from '../../../../../../../data/common'; const fields = [ { diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/group_fields.tsx b/src/plugins/discover/public/application/main/components/sidebar/lib/group_fields.tsx similarity index 97% rename from src/plugins/discover/public/application/apps/main/components/sidebar/lib/group_fields.tsx rename to src/plugins/discover/public/application/main/components/sidebar/lib/group_fields.tsx index 50d742d83c630..e42050dfa216a 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/group_fields.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/lib/group_fields.tsx @@ -8,7 +8,7 @@ import { IndexPatternField } from 'src/plugins/data/public'; import { FieldFilterState, isFieldFiltered } from './field_filter'; -import { getFieldSubtypeMulti } from '../../../../../../../../data/common'; +import { getFieldSubtypeMulti } from '../../../../../../../data/common'; interface GroupedFields { selected: IndexPatternField[]; diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/visualize_trigger_utils.test.ts b/src/plugins/discover/public/application/main/components/sidebar/lib/visualize_trigger_utils.test.ts similarity index 98% rename from src/plugins/discover/public/application/apps/main/components/sidebar/lib/visualize_trigger_utils.test.ts rename to src/plugins/discover/public/application/main/components/sidebar/lib/visualize_trigger_utils.test.ts index 0a61bf1ea6029..3c9b1f89e3cbd 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/visualize_trigger_utils.test.ts +++ b/src/plugins/discover/public/application/main/components/sidebar/lib/visualize_trigger_utils.test.ts @@ -26,7 +26,7 @@ const mockGetActions = jest.fn>>, [string, { fieldN () => Promise.resolve([]) ); -jest.mock('../../../../../../kibana_services', () => ({ +jest.mock('../../../../../kibana_services', () => ({ getUiActions: () => ({ getTriggerCompatibleActions: mockGetActions, }), diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/visualize_trigger_utils.ts b/src/plugins/discover/public/application/main/components/sidebar/lib/visualize_trigger_utils.ts similarity index 95% rename from src/plugins/discover/public/application/apps/main/components/sidebar/lib/visualize_trigger_utils.ts rename to src/plugins/discover/public/application/main/components/sidebar/lib/visualize_trigger_utils.ts index f00b430e5acef..8cee4650a220f 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/lib/visualize_trigger_utils.ts +++ b/src/plugins/discover/public/application/main/components/sidebar/lib/visualize_trigger_utils.ts @@ -11,9 +11,9 @@ import { VISUALIZE_GEO_FIELD_TRIGGER, visualizeFieldTrigger, visualizeGeoFieldTrigger, -} from '../../../../../../../../ui_actions/public'; -import { getUiActions } from '../../../../../../kibana_services'; -import { IndexPatternField, KBN_FIELD_TYPES } from '../../../../../../../../data/public'; +} from '../../../../../../../ui_actions/public'; +import { getUiActions } from '../../../../../kibana_services'; +import { IndexPatternField, KBN_FIELD_TYPES } from '../../../../../../../data/public'; function getTriggerConstant(type: string) { return type === KBN_FIELD_TYPES.GEO_POINT || type === KBN_FIELD_TYPES.GEO_SHAPE diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/string_progress_bar.tsx b/src/plugins/discover/public/application/main/components/sidebar/string_progress_bar.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/sidebar/string_progress_bar.tsx rename to src/plugins/discover/public/application/main/components/sidebar/string_progress_bar.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/types.ts b/src/plugins/discover/public/application/main/components/sidebar/types.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/sidebar/types.ts rename to src/plugins/discover/public/application/main/components/sidebar/types.ts diff --git a/src/plugins/discover/public/application/apps/main/components/skip_bottom_button/index.ts b/src/plugins/discover/public/application/main/components/skip_bottom_button/index.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/skip_bottom_button/index.ts rename to src/plugins/discover/public/application/main/components/skip_bottom_button/index.ts diff --git a/src/plugins/discover/public/application/apps/main/components/skip_bottom_button/skip_bottom_button.scss b/src/plugins/discover/public/application/main/components/skip_bottom_button/skip_bottom_button.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/skip_bottom_button/skip_bottom_button.scss rename to src/plugins/discover/public/application/main/components/skip_bottom_button/skip_bottom_button.scss diff --git a/src/plugins/discover/public/application/apps/main/components/skip_bottom_button/skip_bottom_button.test.tsx b/src/plugins/discover/public/application/main/components/skip_bottom_button/skip_bottom_button.test.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/skip_bottom_button/skip_bottom_button.test.tsx rename to src/plugins/discover/public/application/main/components/skip_bottom_button/skip_bottom_button.test.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/skip_bottom_button/skip_bottom_button.tsx b/src/plugins/discover/public/application/main/components/skip_bottom_button/skip_bottom_button.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/skip_bottom_button/skip_bottom_button.tsx rename to src/plugins/discover/public/application/main/components/skip_bottom_button/skip_bottom_button.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/top_nav/__snapshots__/open_search_panel.test.tsx.snap b/src/plugins/discover/public/application/main/components/top_nav/__snapshots__/open_search_panel.test.tsx.snap similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/top_nav/__snapshots__/open_search_panel.test.tsx.snap rename to src/plugins/discover/public/application/main/components/top_nav/__snapshots__/open_search_panel.test.tsx.snap diff --git a/src/plugins/discover/public/application/apps/main/components/top_nav/discover_topnav.test.tsx b/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.test.tsx similarity index 81% rename from src/plugins/discover/public/application/apps/main/components/top_nav/discover_topnav.test.tsx rename to src/plugins/discover/public/application/main/components/top_nav/discover_topnav.test.tsx index 808346b53304c..2dec7bc991198 100644 --- a/src/plugins/discover/public/application/apps/main/components/top_nav/discover_topnav.test.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.test.tsx @@ -8,14 +8,14 @@ import React from 'react'; import { shallowWithIntl } from '@kbn/test/jest'; -import { indexPatternMock } from '../../../../../__mocks__/index_pattern'; -import { savedSearchMock } from '../../../../../__mocks__/saved_search'; +import { indexPatternMock } from '../../../../__mocks__/index_pattern'; +import { savedSearchMock } from '../../../../__mocks__/saved_search'; import { DiscoverTopNav, DiscoverTopNavProps } from './discover_topnav'; -import { TopNavMenuData } from '../../../../../../../navigation/public'; -import { ISearchSource, Query } from '../../../../../../../data/common'; +import { TopNavMenuData } from '../../../../../../navigation/public'; +import { ISearchSource, Query } from '../../../../../../data/common'; import { GetStateReturn } from '../../services/discover_state'; -import { setHeaderActionMenuMounter } from '../../../../../kibana_services'; -import { discoverServiceMock } from '../../../../../__mocks__/services'; +import { setHeaderActionMenuMounter } from '../../../../kibana_services'; +import { discoverServiceMock } from '../../../../__mocks__/services'; setHeaderActionMenuMounter(jest.fn()); diff --git a/src/plugins/discover/public/application/apps/main/components/top_nav/discover_topnav.tsx b/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx similarity index 95% rename from src/plugins/discover/public/application/apps/main/components/top_nav/discover_topnav.tsx rename to src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx index 5e3e2dfd96954..6af345e25f265 100644 --- a/src/plugins/discover/public/application/apps/main/components/top_nav/discover_topnav.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx @@ -9,8 +9,8 @@ import React, { useCallback, useMemo } from 'react'; import { useHistory } from 'react-router-dom'; import { DiscoverLayoutProps } from '../layout/types'; import { getTopNavLinks } from './get_top_nav_links'; -import { Query, TimeRange } from '../../../../../../../data/common/query'; -import { getHeaderActionMenuMounter } from '../../../../../kibana_services'; +import { Query, TimeRange } from '../../../../../../data/common/query'; +import { getHeaderActionMenuMounter } from '../../../../kibana_services'; import { GetStateReturn } from '../../services/discover_state'; export type DiscoverTopNavProps = Pick< diff --git a/src/plugins/discover/public/application/apps/main/components/top_nav/get_top_nav_links.test.ts b/src/plugins/discover/public/application/main/components/top_nav/get_top_nav_links.test.ts similarity index 91% rename from src/plugins/discover/public/application/apps/main/components/top_nav/get_top_nav_links.test.ts rename to src/plugins/discover/public/application/main/components/top_nav/get_top_nav_links.test.ts index 20c5b9bae332d..6cf37c5333597 100644 --- a/src/plugins/discover/public/application/apps/main/components/top_nav/get_top_nav_links.test.ts +++ b/src/plugins/discover/public/application/main/components/top_nav/get_top_nav_links.test.ts @@ -8,9 +8,9 @@ import { ISearchSource } from 'src/plugins/data/public'; import { getTopNavLinks } from './get_top_nav_links'; -import { indexPatternMock } from '../../../../../__mocks__/index_pattern'; -import { savedSearchMock } from '../../../../../__mocks__/saved_search'; -import { DiscoverServices } from '../../../../../build_services'; +import { indexPatternMock } from '../../../../__mocks__/index_pattern'; +import { savedSearchMock } from '../../../../__mocks__/saved_search'; +import { DiscoverServices } from '../../../../build_services'; import { GetStateReturn } from '../../services/discover_state'; const services = { diff --git a/src/plugins/discover/public/application/apps/main/components/top_nav/get_top_nav_links.ts b/src/plugins/discover/public/application/main/components/top_nav/get_top_nav_links.ts similarity index 92% rename from src/plugins/discover/public/application/apps/main/components/top_nav/get_top_nav_links.ts rename to src/plugins/discover/public/application/main/components/top_nav/get_top_nav_links.ts index 653e878ad01bb..4b9d48a92e0f5 100644 --- a/src/plugins/discover/public/application/apps/main/components/top_nav/get_top_nav_links.ts +++ b/src/plugins/discover/public/application/main/components/top_nav/get_top_nav_links.ts @@ -9,14 +9,14 @@ import { i18n } from '@kbn/i18n'; import type { IndexPattern, ISearchSource } from 'src/plugins/data/common'; import { showOpenSearchPanel } from './show_open_search_panel'; -import { getSharingData, showPublicUrlSwitch } from '../../utils/get_sharing_data'; -import { unhashUrl } from '../../../../../../../kibana_utils/public'; -import { DiscoverServices } from '../../../../../build_services'; -import { SavedSearch } from '../../../../../saved_searches'; +import { getSharingData, showPublicUrlSwitch } from '../../../../utils/get_sharing_data'; +import { unhashUrl } from '../../../../../../kibana_utils/public'; +import { DiscoverServices } from '../../../../build_services'; +import { SavedSearch } from '../../../../services/saved_searches'; import { onSaveSearch } from './on_save_search'; import { GetStateReturn } from '../../services/discover_state'; import { openOptionsPopover } from './open_options_popover'; -import type { TopNavMenuData } from '../../../../../../../navigation/public'; +import type { TopNavMenuData } from '../../../../../../navigation/public'; /** * Helper function to build the top nav links diff --git a/src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.test.tsx b/src/plugins/discover/public/application/main/components/top_nav/on_save_search.test.tsx similarity index 68% rename from src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.test.tsx rename to src/plugins/discover/public/application/main/components/top_nav/on_save_search.test.tsx index 1f0cee0b75672..c0d4a34a4e429 100644 --- a/src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.test.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/on_save_search.test.tsx @@ -6,15 +6,15 @@ * Side Public License, v 1. */ -import { showSaveModal } from '../../../../../../../saved_objects/public'; -jest.mock('../../../../../../../saved_objects/public'); +import { showSaveModal } from '../../../../../../saved_objects/public'; +jest.mock('../../../../../../saved_objects/public'); import { onSaveSearch } from './on_save_search'; -import { indexPatternMock } from '../../../../../__mocks__/index_pattern'; -import { savedSearchMock } from '../../../../../__mocks__/saved_search'; -import { DiscoverServices } from '../../../../../build_services'; +import { indexPatternMock } from '../../../../__mocks__/index_pattern'; +import { savedSearchMock } from '../../../../__mocks__/saved_search'; +import { DiscoverServices } from '../../../../build_services'; import { GetStateReturn } from '../../services/discover_state'; -import { i18nServiceMock } from '../../../../../../../../core/public/mocks'; +import { i18nServiceMock } from '../../../../../../../core/public/mocks'; test('onSaveSearch', async () => { const serviceMock = { diff --git a/src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.tsx b/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx similarity index 94% rename from src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.tsx rename to src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx index 25b04e12c650a..67db4968f9a33 100644 --- a/src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx @@ -8,12 +8,12 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { SavedObjectSaveModal, showSaveModal } from '../../../../../../../saved_objects/public'; -import { SavedSearch, SaveSavedSearchOptions } from '../../../../../saved_searches'; -import { IndexPattern } from '../../../../../../../data/common'; -import { DiscoverServices } from '../../../../../build_services'; +import { SavedObjectSaveModal, showSaveModal } from '../../../../../../saved_objects/public'; +import { SavedSearch, SaveSavedSearchOptions } from '../../../../services/saved_searches'; +import { IndexPattern } from '../../../../../../data/common'; +import { DiscoverServices } from '../../../../build_services'; import { GetStateReturn } from '../../services/discover_state'; -import { setBreadcrumbsTitle } from '../../../../helpers/breadcrumbs'; +import { setBreadcrumbsTitle } from '../../../../utils/breadcrumbs'; import { persistSavedSearch } from '../../utils/persist_saved_search'; async function saveDataSource({ diff --git a/src/plugins/discover/public/application/apps/main/components/top_nav/open_options_popover.scss b/src/plugins/discover/public/application/main/components/top_nav/open_options_popover.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/top_nav/open_options_popover.scss rename to src/plugins/discover/public/application/main/components/top_nav/open_options_popover.scss diff --git a/src/plugins/discover/public/application/apps/main/components/top_nav/open_options_popover.test.tsx b/src/plugins/discover/public/application/main/components/top_nav/open_options_popover.test.tsx similarity index 93% rename from src/plugins/discover/public/application/apps/main/components/top_nav/open_options_popover.test.tsx rename to src/plugins/discover/public/application/main/components/top_nav/open_options_popover.test.tsx index 28e57aed7b660..c9564a3ed029d 100644 --- a/src/plugins/discover/public/application/apps/main/components/top_nav/open_options_popover.test.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/open_options_popover.test.tsx @@ -9,9 +9,9 @@ import React from 'react'; import { mountWithIntl } from '@kbn/test/jest'; import { findTestSubject } from '@elastic/eui/lib/test'; -import { getServices } from '../../../../../kibana_services'; +import { getServices } from '../../../../kibana_services'; -jest.mock('../../../../../kibana_services', () => { +jest.mock('../../../../kibana_services', () => { const mockUiSettings = new Map(); return { getServices: () => ({ diff --git a/src/plugins/discover/public/application/apps/main/components/top_nav/open_options_popover.tsx b/src/plugins/discover/public/application/main/components/top_nav/open_options_popover.tsx similarity index 97% rename from src/plugins/discover/public/application/apps/main/components/top_nav/open_options_popover.tsx rename to src/plugins/discover/public/application/main/components/top_nav/open_options_popover.tsx index 6e90c702c2bfd..1b567813c6f7b 100644 --- a/src/plugins/discover/public/application/apps/main/components/top_nav/open_options_popover.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/open_options_popover.tsx @@ -22,8 +22,8 @@ import { EuiTextAlign, } from '@elastic/eui'; import './open_options_popover.scss'; -import { DOC_TABLE_LEGACY } from '../../../../../../common'; -import { getServices } from '../../../../../kibana_services'; +import { DOC_TABLE_LEGACY } from '../../../../../common'; +import { getServices } from '../../../../kibana_services'; const container = document.createElement('div'); let isOpen = false; diff --git a/src/plugins/discover/public/application/apps/main/components/top_nav/open_search_panel.test.tsx b/src/plugins/discover/public/application/main/components/top_nav/open_search_panel.test.tsx similarity index 96% rename from src/plugins/discover/public/application/apps/main/components/top_nav/open_search_panel.test.tsx rename to src/plugins/discover/public/application/main/components/top_nav/open_search_panel.test.tsx index dc5d3e81744db..80c70d9b1aff5 100644 --- a/src/plugins/discover/public/application/apps/main/components/top_nav/open_search_panel.test.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/open_search_panel.test.tsx @@ -15,7 +15,7 @@ const mockCapabilities = jest.fn().mockReturnValue({ }, }); -jest.mock('../../../../../kibana_services', () => { +jest.mock('../../../../kibana_services', () => { return { getServices: () => ({ core: { uiSettings: {}, savedObjects: {} }, diff --git a/src/plugins/discover/public/application/apps/main/components/top_nav/open_search_panel.tsx b/src/plugins/discover/public/application/main/components/top_nav/open_search_panel.tsx similarity index 95% rename from src/plugins/discover/public/application/apps/main/components/top_nav/open_search_panel.tsx rename to src/plugins/discover/public/application/main/components/top_nav/open_search_panel.tsx index 1b34e6ffa0b9a..e5a175f0511da 100644 --- a/src/plugins/discover/public/application/apps/main/components/top_nav/open_search_panel.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/open_search_panel.tsx @@ -20,8 +20,8 @@ import { EuiFlyoutBody, EuiTitle, } from '@elastic/eui'; -import { SavedObjectFinderUi } from '../../../../../../../saved_objects/public'; -import { getServices } from '../../../../../kibana_services'; +import { SavedObjectFinderUi } from '../../../../../../saved_objects/public'; +import { getServices } from '../../../../kibana_services'; const SEARCH_OBJECT_TYPE = 'search'; diff --git a/src/plugins/discover/public/application/apps/main/components/top_nav/show_open_search_panel.tsx b/src/plugins/discover/public/application/main/components/top_nav/show_open_search_panel.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/top_nav/show_open_search_panel.tsx rename to src/plugins/discover/public/application/main/components/top_nav/show_open_search_panel.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/total_documents/total_documents.tsx b/src/plugins/discover/public/application/main/components/total_documents/total_documents.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/total_documents/total_documents.tsx rename to src/plugins/discover/public/application/main/components/total_documents/total_documents.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/uninitialized/uninitialized.tsx b/src/plugins/discover/public/application/main/components/uninitialized/uninitialized.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/uninitialized/uninitialized.tsx rename to src/plugins/discover/public/application/main/components/uninitialized/uninitialized.tsx diff --git a/src/plugins/discover/public/application/apps/main/discover_main_app.test.tsx b/src/plugins/discover/public/application/main/discover_main_app.test.tsx similarity index 72% rename from src/plugins/discover/public/application/apps/main/discover_main_app.test.tsx rename to src/plugins/discover/public/application/main/discover_main_app.test.tsx index db29da87b4641..cb2bad306f43f 100644 --- a/src/plugins/discover/public/application/apps/main/discover_main_app.test.tsx +++ b/src/plugins/discover/public/application/main/discover_main_app.test.tsx @@ -7,14 +7,14 @@ */ import React from 'react'; import { mountWithIntl } from '@kbn/test/jest'; -import { indexPatternMock } from '../../../__mocks__/index_pattern'; +import { indexPatternMock } from '../../__mocks__/index_pattern'; import { DiscoverMainApp } from './discover_main_app'; -import { discoverServiceMock } from '../../../__mocks__/services'; -import { savedSearchMock } from '../../../__mocks__/saved_search'; -import { createSearchSessionMock } from '../../../__mocks__/search_session'; -import { SavedObject } from '../../../../../../core/types'; -import { IndexPatternAttributes } from '../../../../../data/common'; -import { setHeaderActionMenuMounter } from '../../../kibana_services'; +import { discoverServiceMock } from '../../__mocks__/services'; +import { savedSearchMock } from '../../__mocks__/saved_search'; +import { createSearchSessionMock } from '../../__mocks__/search_session'; +import { SavedObject } from '../../../../../core/types'; +import { IndexPatternAttributes } from '../../../../data/common'; +import { setHeaderActionMenuMounter } from '../../kibana_services'; import { findTestSubject } from '@elastic/eui/lib/test'; setHeaderActionMenuMounter(jest.fn()); diff --git a/src/plugins/discover/public/application/apps/main/discover_main_app.tsx b/src/plugins/discover/public/application/main/discover_main_app.tsx similarity index 90% rename from src/plugins/discover/public/application/apps/main/discover_main_app.tsx rename to src/plugins/discover/public/application/main/discover_main_app.tsx index c7a38032ef405..ea3f852a5290a 100644 --- a/src/plugins/discover/public/application/apps/main/discover_main_app.tsx +++ b/src/plugins/discover/public/application/main/discover_main_app.tsx @@ -8,13 +8,13 @@ import React, { useCallback, useEffect } from 'react'; import { History } from 'history'; import { DiscoverLayout } from './components/layout'; -import { setBreadcrumbsTitle } from '../../helpers/breadcrumbs'; +import { setBreadcrumbsTitle } from '../../utils/breadcrumbs'; import { addHelpMenuToAppChrome } from '../../components/help_menu/help_menu_util'; -import { useDiscoverState } from './services/use_discover_state'; -import { useUrl } from './services/use_url'; -import { IndexPatternAttributes, SavedObject } from '../../../../../data/common'; -import { DiscoverServices } from '../../../build_services'; -import { SavedSearch } from '../../../saved_searches'; +import { useDiscoverState } from './utils/use_discover_state'; +import { useUrl } from './utils/use_url'; +import { IndexPatternAttributes, SavedObject } from '../../../../data/common'; +import { DiscoverServices } from '../../build_services'; +import { SavedSearch } from '../../services/saved_searches'; const DiscoverLayoutMemoized = React.memo(DiscoverLayout); diff --git a/src/plugins/discover/public/application/apps/main/discover_main_route.tsx b/src/plugins/discover/public/application/main/discover_main_route.tsx similarity index 92% rename from src/plugins/discover/public/application/apps/main/discover_main_route.tsx rename to src/plugins/discover/public/application/main/discover_main_route.tsx index b674bfd6568ac..d226e5ef9748b 100644 --- a/src/plugins/discover/public/application/apps/main/discover_main_route.tsx +++ b/src/plugins/discover/public/application/main/discover_main_route.tsx @@ -12,15 +12,19 @@ import { i18n } from '@kbn/i18n'; import { EuiEmptyPrompt } from '@elastic/eui'; import { IndexPatternAttributes, ISearchSource, SavedObject } from 'src/plugins/data/common'; -import { DiscoverServices } from '../../../build_services'; -import { SavedSearch, getSavedSearch, getSavedSearchFullPathUrl } from '../../../saved_searches'; +import { DiscoverServices } from '../../build_services'; +import { + SavedSearch, + getSavedSearch, + getSavedSearchFullPathUrl, +} from '../../services/saved_searches'; import { getState } from './services/discover_state'; import { loadIndexPattern, resolveIndexPattern } from './utils/resolve_index_pattern'; import { DiscoverMainApp } from './discover_main_app'; -import { getRootBreadcrumbs, getSavedSearchBreadcrumbs } from '../../helpers/breadcrumbs'; -import { redirectWhenMissing } from '../../../../../kibana_utils/public'; -import { DataViewSavedObjectConflictError } from '../../../../../data_views/common'; -import { getUrlTracker } from '../../../kibana_services'; +import { getRootBreadcrumbs, getSavedSearchBreadcrumbs } from '../../utils/breadcrumbs'; +import { redirectWhenMissing } from '../../../../kibana_utils/public'; +import { DataViewSavedObjectConflictError } from '../../../../data_views/common'; +import { getUrlTracker } from '../../kibana_services'; import { LoadingIndicator } from '../../components/common/loading_indicator'; const DiscoverMainAppMemoized = memo(DiscoverMainApp); diff --git a/src/plugins/discover/public/application/apps/main/index.ts b/src/plugins/discover/public/application/main/index.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/index.ts rename to src/plugins/discover/public/application/main/index.ts diff --git a/src/plugins/discover/public/application/apps/main/services/discover_search_session.test.ts b/src/plugins/discover/public/application/main/services/discover_search_session.test.ts similarity index 97% rename from src/plugins/discover/public/application/apps/main/services/discover_search_session.test.ts rename to src/plugins/discover/public/application/main/services/discover_search_session.test.ts index 97c6ada3636d5..0f854438b6749 100644 --- a/src/plugins/discover/public/application/apps/main/services/discover_search_session.test.ts +++ b/src/plugins/discover/public/application/main/services/discover_search_session.test.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { createSearchSessionMock } from '../../../../__mocks__/search_session'; +import { createSearchSessionMock } from '../../../__mocks__/search_session'; describe('DiscoverSearchSessionManager', () => { const { history, session, searchSessionManager } = createSearchSessionMock(); diff --git a/src/plugins/discover/public/application/apps/main/services/discover_search_session.ts b/src/plugins/discover/public/application/main/services/discover_search_session.ts similarity index 93% rename from src/plugins/discover/public/application/apps/main/services/discover_search_session.ts rename to src/plugins/discover/public/application/main/services/discover_search_session.ts index 81ab578229d19..41e1ad37a353c 100644 --- a/src/plugins/discover/public/application/apps/main/services/discover_search_session.ts +++ b/src/plugins/discover/public/application/main/services/discover_search_session.ts @@ -8,13 +8,13 @@ import { History } from 'history'; import { filter } from 'rxjs/operators'; -import { DataPublicPluginStart } from '../../../../../../data/public'; +import { DataPublicPluginStart } from '../../../../../data/public'; import { createQueryParamObservable, getQueryParams, removeQueryParam, -} from '../../../../../../kibana_utils/public'; -import { SEARCH_SESSION_ID_QUERY_PARAM } from '../../../../url_generator'; +} from '../../../../../kibana_utils/public'; +import { SEARCH_SESSION_ID_QUERY_PARAM } from '../../../url_generator'; export interface DiscoverSearchSessionManagerDeps { history: History; diff --git a/src/plugins/discover/public/application/apps/main/services/discover_state.test.ts b/src/plugins/discover/public/application/main/services/discover_state.test.ts similarity index 97% rename from src/plugins/discover/public/application/apps/main/services/discover_state.test.ts rename to src/plugins/discover/public/application/main/services/discover_state.test.ts index 7f875be0a42c5..5c9900c6a2d78 100644 --- a/src/plugins/discover/public/application/apps/main/services/discover_state.test.ts +++ b/src/plugins/discover/public/application/main/services/discover_state.test.ts @@ -13,9 +13,9 @@ import { createSearchSessionRestorationDataProvider, } from './discover_state'; import { createBrowserHistory, History } from 'history'; -import { dataPluginMock } from '../../../../../../data/public/mocks'; -import type { SavedSearch } from '../../../../saved_searches'; -import { SEARCH_FIELDS_FROM_SOURCE } from '../../../../../common'; +import { dataPluginMock } from '../../../../../data/public/mocks'; +import type { SavedSearch } from '../../../services/saved_searches'; +import { SEARCH_FIELDS_FROM_SOURCE } from '../../../../common'; let history: History; let state: GetStateReturn; diff --git a/src/plugins/discover/public/application/apps/main/services/discover_state.ts b/src/plugins/discover/public/application/main/services/discover_state.ts similarity index 96% rename from src/plugins/discover/public/application/apps/main/services/discover_state.ts rename to src/plugins/discover/public/application/main/services/discover_state.ts index 388d4f19d1c27..66e013e8f20ea 100644 --- a/src/plugins/discover/public/application/apps/main/services/discover_state.ts +++ b/src/plugins/discover/public/application/main/services/discover_state.ts @@ -18,7 +18,7 @@ import { StateContainer, syncState, withNotifyOnErrors, -} from '../../../../../../kibana_utils/public'; +} from '../../../../../kibana_utils/public'; import { connectToQueryState, DataPublicPluginStart, @@ -29,13 +29,13 @@ import { Query, SearchSessionInfoProvider, syncQueryStateWithUrl, -} from '../../../../../../data/public'; -import { migrateLegacyQuery } from '../../../helpers/migrate_legacy_query'; +} from '../../../../../data/public'; +import { migrateLegacyQuery } from '../../../utils/migrate_legacy_query'; import { DiscoverGridSettings } from '../../../components/discover_grid/types'; -import { SavedSearch } from '../../../../saved_searches'; -import { handleSourceColumnState } from '../../../helpers/state_helpers'; -import { DISCOVER_APP_LOCATOR, DiscoverAppLocatorParams } from '../../../../locator'; -import { VIEW_MODE } from '../components/view_mode_toggle'; +import { SavedSearch } from '../../../services/saved_searches'; +import { handleSourceColumnState } from '../../../utils/state_helpers'; +import { DISCOVER_APP_LOCATOR, DiscoverAppLocatorParams } from '../../../locator'; +import { VIEW_MODE } from '../../../components/view_mode_toggle'; export interface AppState { /** diff --git a/src/plugins/discover/public/application/apps/main/utils/calc_field_counts.test.ts b/src/plugins/discover/public/application/main/utils/calc_field_counts.test.ts similarity index 90% rename from src/plugins/discover/public/application/apps/main/utils/calc_field_counts.test.ts rename to src/plugins/discover/public/application/main/utils/calc_field_counts.test.ts index a13fd88df7c25..9d198947e06c7 100644 --- a/src/plugins/discover/public/application/apps/main/utils/calc_field_counts.test.ts +++ b/src/plugins/discover/public/application/main/utils/calc_field_counts.test.ts @@ -7,8 +7,8 @@ */ import { calcFieldCounts } from './calc_field_counts'; -import { indexPatternMock } from '../../../../__mocks__/index_pattern'; -import { ElasticSearchHit } from '../../../doc_views/doc_views_types'; +import { indexPatternMock } from '../../../__mocks__/index_pattern'; +import { ElasticSearchHit } from '../../../services/doc_views/doc_views_types'; describe('calcFieldCounts', () => { test('returns valid field count data', async () => { diff --git a/src/plugins/discover/public/application/apps/main/utils/calc_field_counts.ts b/src/plugins/discover/public/application/main/utils/calc_field_counts.ts similarity index 86% rename from src/plugins/discover/public/application/apps/main/utils/calc_field_counts.ts rename to src/plugins/discover/public/application/main/utils/calc_field_counts.ts index 2198d2f66b6b4..08d1a2639fa0b 100644 --- a/src/plugins/discover/public/application/apps/main/utils/calc_field_counts.ts +++ b/src/plugins/discover/public/application/main/utils/calc_field_counts.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ -import { flattenHit, IndexPattern } from '../../../../../../data/common'; -import { ElasticSearchHit } from '../../../doc_views/doc_views_types'; +import { flattenHit, IndexPattern } from '../../../../../data/common'; +import { ElasticSearchHit } from '../../../services/doc_views/doc_views_types'; /** * This function is recording stats of the available fields, for usage in sidebar and sharing diff --git a/src/plugins/discover/public/application/apps/main/utils/fetch_all.test.ts b/src/plugins/discover/public/application/main/utils/fetch_all.test.ts similarity index 85% rename from src/plugins/discover/public/application/apps/main/utils/fetch_all.test.ts rename to src/plugins/discover/public/application/main/utils/fetch_all.test.ts index 88830b2946b5f..9f17054de18d4 100644 --- a/src/plugins/discover/public/application/apps/main/utils/fetch_all.test.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_all.test.ts @@ -5,13 +5,13 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { FetchStatus } from '../../../types'; +import { FetchStatus } from '../../types'; import { BehaviorSubject } from 'rxjs'; -import { RequestAdapter } from '../../../../../../inspector'; -import { savedSearchMock } from '../../../../__mocks__/saved_search'; -import { ReduxLikeStateContainer } from '../../../../../../kibana_utils/common'; +import { RequestAdapter } from '../../../../../inspector'; +import { savedSearchMock } from '../../../__mocks__/saved_search'; +import { ReduxLikeStateContainer } from '../../../../../kibana_utils/common'; import { AppState } from '../services/discover_state'; -import { discoverServiceMock } from '../../../../__mocks__/services'; +import { discoverServiceMock } from '../../../__mocks__/services'; import { fetchAll } from './fetch_all'; describe('test fetchAll', () => { diff --git a/src/plugins/discover/public/application/apps/main/utils/fetch_all.ts b/src/plugins/discover/public/application/main/utils/fetch_all.ts similarity index 82% rename from src/plugins/discover/public/application/apps/main/utils/fetch_all.ts rename to src/plugins/discover/public/application/main/utils/fetch_all.ts index e9d9335abcda0..efaa349181fb6 100644 --- a/src/plugins/discover/public/application/apps/main/utils/fetch_all.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_all.ts @@ -12,20 +12,20 @@ import { sendLoadingMsg, sendPartialMsg, sendResetMsg, -} from '../services/use_saved_search_messages'; +} from './use_saved_search_messages'; import { updateSearchSource } from './update_search_source'; -import type { SortOrder } from '../../../../saved_searches'; +import type { SortOrder } from '../../../services/saved_searches'; import { fetchDocuments } from './fetch_documents'; import { fetchTotalHits } from './fetch_total_hits'; import { fetchChart } from './fetch_chart'; -import { ISearchSource } from '../../../../../../data/common'; -import { Adapters } from '../../../../../../inspector'; +import { ISearchSource } from '../../../../../data/common'; +import { Adapters } from '../../../../../inspector'; import { AppState } from '../services/discover_state'; -import { FetchStatus } from '../../../types'; -import { DataPublicPluginStart } from '../../../../../../data/public'; -import { SavedSearchData } from '../services/use_saved_search'; -import { DiscoverServices } from '../../../../build_services'; -import { ReduxLikeStateContainer } from '../../../../../../kibana_utils/common'; +import { FetchStatus } from '../../types'; +import { DataPublicPluginStart } from '../../../../../data/public'; +import { SavedSearchData } from './use_saved_search'; +import { DiscoverServices } from '../../../build_services'; +import { ReduxLikeStateContainer } from '../../../../../kibana_utils/common'; export function fetchAll( dataSubjects: SavedSearchData, diff --git a/src/plugins/discover/public/application/apps/main/utils/fetch_chart.test.ts b/src/plugins/discover/public/application/main/utils/fetch_chart.test.ts similarity index 93% rename from src/plugins/discover/public/application/apps/main/utils/fetch_chart.test.ts rename to src/plugins/discover/public/application/main/utils/fetch_chart.test.ts index 2c9350b457779..5f57484aaa653 100644 --- a/src/plugins/discover/public/application/apps/main/utils/fetch_chart.test.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_chart.test.ts @@ -5,15 +5,15 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { FetchStatus } from '../../../types'; +import { FetchStatus } from '../../types'; import { BehaviorSubject, of, throwError as throwErrorRx } from 'rxjs'; -import { RequestAdapter } from '../../../../../../inspector'; -import { savedSearchMockWithTimeField } from '../../../../__mocks__/saved_search'; +import { RequestAdapter } from '../../../../../inspector'; +import { savedSearchMockWithTimeField } from '../../../__mocks__/saved_search'; import { fetchChart, updateSearchSource } from './fetch_chart'; -import { ReduxLikeStateContainer } from '../../../../../../kibana_utils/common'; +import { ReduxLikeStateContainer } from '../../../../../kibana_utils/common'; import { AppState } from '../services/discover_state'; -import { discoverServiceMock } from '../../../../__mocks__/services'; -import { calculateBounds, IKibanaSearchResponse } from '../../../../../../data/common'; +import { discoverServiceMock } from '../../../__mocks__/services'; +import { calculateBounds, IKibanaSearchResponse } from '../../../../../data/common'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; function getDataSubjects() { diff --git a/src/plugins/discover/public/application/apps/main/utils/fetch_chart.ts b/src/plugins/discover/public/application/main/utils/fetch_chart.ts similarity index 89% rename from src/plugins/discover/public/application/apps/main/utils/fetch_chart.ts rename to src/plugins/discover/public/application/main/utils/fetch_chart.ts index 50f3a1b8bfea7..59377970acb12 100644 --- a/src/plugins/discover/public/application/apps/main/utils/fetch_chart.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_chart.ts @@ -12,16 +12,16 @@ import { isCompleteResponse, search, ISearchSource, -} from '../../../../../../data/public'; -import { Adapters } from '../../../../../../inspector'; +} from '../../../../../data/public'; +import { Adapters } from '../../../../../inspector'; import { getChartAggConfigs, getDimensions } from './index'; -import { tabifyAggResponse } from '../../../../../../data/common'; +import { tabifyAggResponse } from '../../../../../data/common'; import { buildPointSeriesData } from '../components/chart/point_series'; -import { FetchStatus } from '../../../types'; -import { SavedSearchData } from '../services/use_saved_search'; +import { FetchStatus } from '../../types'; +import { SavedSearchData } from './use_saved_search'; import { AppState } from '../services/discover_state'; -import { ReduxLikeStateContainer } from '../../../../../../kibana_utils/common'; -import { sendErrorMsg, sendLoadingMsg } from '../services/use_saved_search_messages'; +import { ReduxLikeStateContainer } from '../../../../../kibana_utils/common'; +import { sendErrorMsg, sendLoadingMsg } from './use_saved_search_messages'; export function fetchChart( data$: SavedSearchData, diff --git a/src/plugins/discover/public/application/apps/main/utils/fetch_documents.test.ts b/src/plugins/discover/public/application/main/utils/fetch_documents.test.ts similarity index 91% rename from src/plugins/discover/public/application/apps/main/utils/fetch_documents.test.ts rename to src/plugins/discover/public/application/main/utils/fetch_documents.test.ts index 6c6c7595b166e..291da255b5068 100644 --- a/src/plugins/discover/public/application/apps/main/utils/fetch_documents.test.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_documents.test.ts @@ -6,11 +6,11 @@ * Side Public License, v 1. */ import { fetchDocuments } from './fetch_documents'; -import { FetchStatus } from '../../../types'; +import { FetchStatus } from '../../types'; import { BehaviorSubject, throwError as throwErrorRx } from 'rxjs'; -import { RequestAdapter } from '../../../../../../inspector'; -import { savedSearchMock } from '../../../../__mocks__/saved_search'; -import { discoverServiceMock } from '../../../../__mocks__/services'; +import { RequestAdapter } from '../../../../../inspector'; +import { savedSearchMock } from '../../../__mocks__/saved_search'; +import { discoverServiceMock } from '../../../__mocks__/services'; function getDataSubjects() { return { diff --git a/src/plugins/discover/public/application/apps/main/utils/fetch_documents.ts b/src/plugins/discover/public/application/main/utils/fetch_documents.ts similarity index 86% rename from src/plugins/discover/public/application/apps/main/utils/fetch_documents.ts rename to src/plugins/discover/public/application/main/utils/fetch_documents.ts index 6c5eff7cff702..0c80aee3f909d 100644 --- a/src/plugins/discover/public/application/apps/main/utils/fetch_documents.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_documents.ts @@ -7,13 +7,13 @@ */ import { i18n } from '@kbn/i18n'; import { filter } from 'rxjs/operators'; -import { Adapters } from '../../../../../../inspector/common'; -import { isCompleteResponse, ISearchSource } from '../../../../../../data/common'; -import { FetchStatus } from '../../../types'; -import { SavedSearchData } from '../services/use_saved_search'; -import { sendErrorMsg, sendLoadingMsg } from '../services/use_saved_search_messages'; -import { SAMPLE_SIZE_SETTING } from '../../../../../common'; -import { DiscoverServices } from '../../../../build_services'; +import { Adapters } from '../../../../../inspector/common'; +import { isCompleteResponse, ISearchSource } from '../../../../../data/common'; +import { FetchStatus } from '../../types'; +import { SavedSearchData } from './use_saved_search'; +import { sendErrorMsg, sendLoadingMsg } from './use_saved_search_messages'; +import { SAMPLE_SIZE_SETTING } from '../../../../common'; +import { DiscoverServices } from '../../../build_services'; export const fetchDocuments = ( data$: SavedSearchData, diff --git a/src/plugins/discover/public/application/apps/main/utils/fetch_total_hits.test.ts b/src/plugins/discover/public/application/main/utils/fetch_total_hits.test.ts similarity index 91% rename from src/plugins/discover/public/application/apps/main/utils/fetch_total_hits.test.ts rename to src/plugins/discover/public/application/main/utils/fetch_total_hits.test.ts index 82a3a2fee6912..c593c9c157422 100644 --- a/src/plugins/discover/public/application/apps/main/utils/fetch_total_hits.test.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_total_hits.test.ts @@ -5,12 +5,12 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { FetchStatus } from '../../../types'; +import { FetchStatus } from '../../types'; import { BehaviorSubject, throwError as throwErrorRx } from 'rxjs'; -import { RequestAdapter } from '../../../../../../inspector'; -import { savedSearchMock } from '../../../../__mocks__/saved_search'; +import { RequestAdapter } from '../../../../../inspector'; +import { savedSearchMock } from '../../../__mocks__/saved_search'; import { fetchTotalHits } from './fetch_total_hits'; -import { discoverServiceMock } from '../../../../__mocks__/services'; +import { discoverServiceMock } from '../../../__mocks__/services'; function getDataSubjects() { return { diff --git a/src/plugins/discover/public/application/apps/main/utils/fetch_total_hits.ts b/src/plugins/discover/public/application/main/utils/fetch_total_hits.ts similarity index 89% rename from src/plugins/discover/public/application/apps/main/utils/fetch_total_hits.ts rename to src/plugins/discover/public/application/main/utils/fetch_total_hits.ts index cfab0d17fcd54..b80dfa9b31e7e 100644 --- a/src/plugins/discover/public/application/apps/main/utils/fetch_total_hits.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_total_hits.ts @@ -12,11 +12,11 @@ import { DataPublicPluginStart, isCompleteResponse, ISearchSource, -} from '../../../../../../data/public'; -import { Adapters } from '../../../../../../inspector/common'; -import { FetchStatus } from '../../../types'; -import { SavedSearchData } from '../services/use_saved_search'; -import { sendErrorMsg, sendLoadingMsg } from '../services/use_saved_search_messages'; +} from '../../../../../data/public'; +import { Adapters } from '../../../../../inspector/common'; +import { FetchStatus } from '../../types'; +import { SavedSearchData } from './use_saved_search'; +import { sendErrorMsg, sendLoadingMsg } from './use_saved_search_messages'; export function fetchTotalHits( data$: SavedSearchData, diff --git a/src/plugins/discover/public/application/apps/main/utils/get_chart_agg_config.test.ts b/src/plugins/discover/public/application/main/utils/get_chart_agg_config.test.ts similarity index 87% rename from src/plugins/discover/public/application/apps/main/utils/get_chart_agg_config.test.ts rename to src/plugins/discover/public/application/main/utils/get_chart_agg_config.test.ts index 515565f0062c9..9960b18181ceb 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_chart_agg_config.test.ts +++ b/src/plugins/discover/public/application/main/utils/get_chart_agg_config.test.ts @@ -5,9 +5,9 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { indexPatternWithTimefieldMock } from '../../../../__mocks__/index_pattern_with_timefield'; -import { ISearchSource } from '../../../../../../data/public'; -import { dataPluginMock } from '../../../../../../data/public/mocks'; +import { indexPatternWithTimefieldMock } from '../../../__mocks__/index_pattern_with_timefield'; +import { ISearchSource } from '../../../../../data/public'; +import { dataPluginMock } from '../../../../../data/public/mocks'; import { getChartAggConfigs } from './get_chart_agg_configs'; describe('getChartAggConfigs', () => { diff --git a/src/plugins/discover/public/application/apps/main/utils/get_chart_agg_configs.ts b/src/plugins/discover/public/application/main/utils/get_chart_agg_configs.ts similarity index 88% rename from src/plugins/discover/public/application/apps/main/utils/get_chart_agg_configs.ts rename to src/plugins/discover/public/application/main/utils/get_chart_agg_configs.ts index 65f98f72beec0..e33fe48302a04 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_chart_agg_configs.ts +++ b/src/plugins/discover/public/application/main/utils/get_chart_agg_configs.ts @@ -5,8 +5,8 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { ISearchSource } from '../../../../../../data/common'; -import { DataPublicPluginStart } from '../../../../../../data/public'; +import { ISearchSource } from '../../../../../data/common'; +import { DataPublicPluginStart } from '../../../../../data/public'; /** * Helper function to apply or remove aggregations to a given search source used for gaining data diff --git a/src/plugins/discover/public/application/apps/main/utils/get_dimensions.test.ts b/src/plugins/discover/public/application/main/utils/get_dimensions.test.ts similarity index 89% rename from src/plugins/discover/public/application/apps/main/utils/get_dimensions.test.ts rename to src/plugins/discover/public/application/main/utils/get_dimensions.test.ts index 35a6e955fe5b2..56822a614ece7 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_dimensions.test.ts +++ b/src/plugins/discover/public/application/main/utils/get_dimensions.test.ts @@ -5,11 +5,11 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { dataPluginMock } from '../../../../../../data/public/mocks'; +import { dataPluginMock } from '../../../../../data/public/mocks'; import { getDimensions } from './get_dimensions'; -import { indexPatternWithTimefieldMock } from '../../../../__mocks__/index_pattern_with_timefield'; -import { ISearchSource, calculateBounds } from '../../../../../../data/common'; +import { indexPatternWithTimefieldMock } from '../../../__mocks__/index_pattern_with_timefield'; +import { ISearchSource, calculateBounds } from '../../../../../data/common'; import { getChartAggConfigs } from './get_chart_agg_configs'; test('getDimensions', () => { diff --git a/src/plugins/discover/public/application/apps/main/utils/get_dimensions.ts b/src/plugins/discover/public/application/main/utils/get_dimensions.ts similarity index 92% rename from src/plugins/discover/public/application/apps/main/utils/get_dimensions.ts rename to src/plugins/discover/public/application/main/utils/get_dimensions.ts index 40b378f1c1698..6fb9cd7865c4f 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_dimensions.ts +++ b/src/plugins/discover/public/application/main/utils/get_dimensions.ts @@ -7,8 +7,8 @@ */ import moment from 'moment'; import dateMath from '@elastic/datemath'; -import { IAggConfigs } from '../../../../../../data/common'; -import { DataPublicPluginStart, search } from '../../../../../../data/public'; +import { IAggConfigs } from '../../../../../data/common'; +import { DataPublicPluginStart, search } from '../../../../../data/public'; import { Dimensions, HistogramParamsBounds } from '../components/chart/point_series'; export function getDimensions( diff --git a/src/plugins/discover/public/application/apps/main/utils/get_fetch_observable.ts b/src/plugins/discover/public/application/main/utils/get_fetch_observable.ts similarity index 93% rename from src/plugins/discover/public/application/apps/main/utils/get_fetch_observable.ts rename to src/plugins/discover/public/application/main/utils/get_fetch_observable.ts index de79a9425f17c..8c0d614f7ac61 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_fetch_observable.ts +++ b/src/plugins/discover/public/application/main/utils/get_fetch_observable.ts @@ -8,13 +8,13 @@ import { merge } from 'rxjs'; import { debounceTime, filter, skip, tap } from 'rxjs/operators'; -import { FetchStatus } from '../../../types'; +import { FetchStatus } from '../../types'; import type { AutoRefreshDoneFn, DataPublicPluginStart, ISearchSource, -} from '../../../../../../data/public'; -import { DataMain$, DataRefetch$ } from '../services/use_saved_search'; +} from '../../../../../data/public'; +import { DataMain$, DataRefetch$ } from './use_saved_search'; import { DiscoverSearchSessionManager } from '../services/discover_search_session'; /** diff --git a/src/plugins/discover/public/application/apps/main/utils/get_fetch_observeable.test.ts b/src/plugins/discover/public/application/main/utils/get_fetch_observeable.test.ts similarity index 91% rename from src/plugins/discover/public/application/apps/main/utils/get_fetch_observeable.test.ts rename to src/plugins/discover/public/application/main/utils/get_fetch_observeable.test.ts index 39873ff609d64..58fcc20396dee 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_fetch_observeable.test.ts +++ b/src/plugins/discover/public/application/main/utils/get_fetch_observeable.test.ts @@ -6,12 +6,12 @@ * Side Public License, v 1. */ import { getFetch$ } from './get_fetch_observable'; -import { FetchStatus } from '../../../types'; +import { FetchStatus } from '../../types'; import { BehaviorSubject, Subject } from 'rxjs'; -import { DataPublicPluginStart } from '../../../../../../data/public'; -import { createSearchSessionMock } from '../../../../__mocks__/search_session'; -import { DataRefetch$ } from '../services/use_saved_search'; -import { savedSearchMock, savedSearchMockWithTimeField } from '../../../../__mocks__/saved_search'; +import { DataPublicPluginStart } from '../../../../../data/public'; +import { createSearchSessionMock } from '../../../__mocks__/search_session'; +import { DataRefetch$ } from './use_saved_search'; +import { savedSearchMock, savedSearchMockWithTimeField } from '../../../__mocks__/saved_search'; function createDataMock( queryString$: Subject, diff --git a/src/plugins/discover/public/application/apps/main/utils/get_result_state.test.ts b/src/plugins/discover/public/application/main/utils/get_result_state.test.ts similarity index 97% rename from src/plugins/discover/public/application/apps/main/utils/get_result_state.test.ts rename to src/plugins/discover/public/application/main/utils/get_result_state.test.ts index 7066d22d6aac7..8dd98650f30a5 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_result_state.test.ts +++ b/src/plugins/discover/public/application/main/utils/get_result_state.test.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ import { getResultState, resultStatuses } from './get_result_state'; -import { FetchStatus } from '../../../types'; +import { FetchStatus } from '../../types'; describe('getResultState', () => { test('fetching uninitialized', () => { diff --git a/src/plugins/discover/public/application/apps/main/utils/get_result_state.ts b/src/plugins/discover/public/application/main/utils/get_result_state.ts similarity index 96% rename from src/plugins/discover/public/application/apps/main/utils/get_result_state.ts rename to src/plugins/discover/public/application/main/utils/get_result_state.ts index 424d2feabd830..ceb6de0cc7798 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_result_state.ts +++ b/src/plugins/discover/public/application/main/utils/get_result_state.ts @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { FetchStatus } from '../../../types'; +import { FetchStatus } from '../../types'; export const resultStatuses = { UNINITIALIZED: 'uninitialized', diff --git a/src/plugins/discover/public/application/apps/main/utils/get_state_defaults.test.ts b/src/plugins/discover/public/application/main/utils/get_state_defaults.test.ts similarity index 84% rename from src/plugins/discover/public/application/apps/main/utils/get_state_defaults.test.ts rename to src/plugins/discover/public/application/main/utils/get_state_defaults.test.ts index 6cf34fd8cb024..0d38b1997716b 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_state_defaults.test.ts +++ b/src/plugins/discover/public/application/main/utils/get_state_defaults.test.ts @@ -7,12 +7,12 @@ */ import { getStateDefaults } from './get_state_defaults'; -import { createSearchSourceMock, dataPluginMock } from '../../../../../../data/public/mocks'; -import { uiSettingsMock } from '../../../../__mocks__/ui_settings'; -import { indexPatternWithTimefieldMock } from '../../../../__mocks__/index_pattern_with_timefield'; -import { savedSearchMock } from '../../../../__mocks__/saved_search'; -import { indexPatternMock } from '../../../../__mocks__/index_pattern'; -import { discoverServiceMock } from '../../../../__mocks__/services'; +import { createSearchSourceMock, dataPluginMock } from '../../../../../data/public/mocks'; +import { uiSettingsMock } from '../../../__mocks__/ui_settings'; +import { indexPatternWithTimefieldMock } from '../../../__mocks__/index_pattern_with_timefield'; +import { savedSearchMock } from '../../../__mocks__/saved_search'; +import { indexPatternMock } from '../../../__mocks__/index_pattern'; +import { discoverServiceMock } from '../../../__mocks__/services'; describe('getStateDefaults', () => { const storage = discoverServiceMock.storage; diff --git a/src/plugins/discover/public/application/apps/main/utils/get_state_defaults.ts b/src/plugins/discover/public/application/main/utils/get_state_defaults.ts similarity index 89% rename from src/plugins/discover/public/application/apps/main/utils/get_state_defaults.ts rename to src/plugins/discover/public/application/main/utils/get_state_defaults.ts index 50dab0273d461..4694bec4057b0 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_state_defaults.ts +++ b/src/plugins/discover/public/application/main/utils/get_state_defaults.ts @@ -12,14 +12,14 @@ import { DEFAULT_COLUMNS_SETTING, SEARCH_FIELDS_FROM_SOURCE, SORT_DEFAULT_ORDER_SETTING, -} from '../../../../../common'; -import { SavedSearch } from '../../../../saved_searches'; -import { DataPublicPluginStart } from '../../../../../../data/public'; +} from '../../../../common'; +import { SavedSearch } from '../../../services/saved_searches'; +import { DataPublicPluginStart } from '../../../../../data/public'; import { AppState } from '../services/discover_state'; -import { getDefaultSort, getSortArray } from '../components/doc_table'; +import { getDefaultSort, getSortArray } from '../../../components/doc_table'; import { CHART_HIDDEN_KEY } from '../components/chart/discover_chart'; -import { Storage } from '../../../../../../kibana_utils/public'; +import { Storage } from '../../../../../kibana_utils/public'; function getDefaultColumns(savedSearch: SavedSearch, config: IUiSettingsClient) { if (savedSearch.columns && savedSearch.columns.length > 0) { diff --git a/src/plugins/discover/public/application/apps/main/utils/get_switch_index_pattern_app_state.test.ts b/src/plugins/discover/public/application/main/utils/get_switch_index_pattern_app_state.test.ts similarity index 98% rename from src/plugins/discover/public/application/apps/main/utils/get_switch_index_pattern_app_state.test.ts rename to src/plugins/discover/public/application/main/utils/get_switch_index_pattern_app_state.test.ts index 83107d6c57ab8..412ad060b5565 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_switch_index_pattern_app_state.test.ts +++ b/src/plugins/discover/public/application/main/utils/get_switch_index_pattern_app_state.test.ts @@ -7,7 +7,7 @@ */ import { getSwitchIndexPatternAppState } from './get_switch_index_pattern_app_state'; -import { IndexPattern } from '../../../../../../data/common'; +import { IndexPattern } from '../../../../../data/common'; /** * Helper function returning an index pattern diff --git a/src/plugins/discover/public/application/apps/main/utils/get_switch_index_pattern_app_state.ts b/src/plugins/discover/public/application/main/utils/get_switch_index_pattern_app_state.ts similarity index 95% rename from src/plugins/discover/public/application/apps/main/utils/get_switch_index_pattern_app_state.ts rename to src/plugins/discover/public/application/main/utils/get_switch_index_pattern_app_state.ts index ff082587172a0..b6dfe7a63f3a8 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_switch_index_pattern_app_state.ts +++ b/src/plugins/discover/public/application/main/utils/get_switch_index_pattern_app_state.ts @@ -7,7 +7,7 @@ */ import type { IndexPattern } from 'src/plugins/data/common'; -import { getSortArray, SortPairArr } from '../components/doc_table/lib/get_sort'; +import { getSortArray, SortPairArr } from '../../../components/doc_table/lib/get_sort'; /** * Helper function to remove or adapt the currently selected columns/sort to be valid with the next diff --git a/src/plugins/discover/public/application/apps/main/utils/index.ts b/src/plugins/discover/public/application/main/utils/index.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/utils/index.ts rename to src/plugins/discover/public/application/main/utils/index.ts diff --git a/src/plugins/discover/public/application/apps/main/utils/nested_fields.ts b/src/plugins/discover/public/application/main/utils/nested_fields.ts similarity index 97% rename from src/plugins/discover/public/application/apps/main/utils/nested_fields.ts rename to src/plugins/discover/public/application/main/utils/nested_fields.ts index beeca801457a1..f06f3dd554b4c 100644 --- a/src/plugins/discover/public/application/apps/main/utils/nested_fields.ts +++ b/src/plugins/discover/public/application/main/utils/nested_fields.ts @@ -8,7 +8,7 @@ import { escapeRegExp } from 'lodash/fp'; import type { IndexPattern } from 'src/plugins/data/public'; -import { getFieldSubtypeNested } from '../../../../../../data/common'; +import { getFieldSubtypeNested } from '../../../../../data/common'; /** * This function checks if the given field in a given index pattern is a nested field's parent. diff --git a/src/plugins/discover/public/application/apps/main/utils/persist_saved_search.ts b/src/plugins/discover/public/application/main/utils/persist_saved_search.ts similarity index 82% rename from src/plugins/discover/public/application/apps/main/utils/persist_saved_search.ts rename to src/plugins/discover/public/application/main/utils/persist_saved_search.ts index fa566fd485942..dcc0f804c27e0 100644 --- a/src/plugins/discover/public/application/apps/main/utils/persist_saved_search.ts +++ b/src/plugins/discover/public/application/main/utils/persist_saved_search.ts @@ -7,13 +7,13 @@ */ import { updateSearchSource } from './update_search_source'; -import { IndexPattern } from '../../../../../../data/public'; -import { SavedSearch } from '../../../../saved_searches'; +import { IndexPattern } from '../../../../../data/public'; +import { SavedSearch } from '../../../services/saved_searches'; import { AppState } from '../services/discover_state'; -import type { SortOrder } from '../../../../saved_searches'; -import { SavedObjectSaveOpts } from '../../../../../../saved_objects/public'; -import { DiscoverServices } from '../../../../build_services'; -import { saveSavedSearch } from '../../../../saved_searches'; +import type { SortOrder } from '../../../services/saved_searches'; +import { SavedObjectSaveOpts } from '../../../../../saved_objects/public'; +import { DiscoverServices } from '../../../build_services'; +import { saveSavedSearch } from '../../../services/saved_searches'; /** * Helper function to update and persist the given savedSearch diff --git a/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.test.ts b/src/plugins/discover/public/application/main/utils/resolve_index_pattern.test.ts similarity index 89% rename from src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.test.ts rename to src/plugins/discover/public/application/main/utils/resolve_index_pattern.test.ts index 56c4f8e6cd1b6..bcf764b57d8cc 100644 --- a/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.test.ts +++ b/src/plugins/discover/public/application/main/utils/resolve_index_pattern.test.ts @@ -11,9 +11,9 @@ import { getFallbackIndexPatternId, IndexPatternSavedObject, } from './resolve_index_pattern'; -import { indexPatternsMock } from '../../../../__mocks__/index_patterns'; -import { indexPatternMock } from '../../../../__mocks__/index_pattern'; -import { configMock } from '../../../../__mocks__/config'; +import { indexPatternsMock } from '../../../__mocks__/index_patterns'; +import { indexPatternMock } from '../../../__mocks__/index_pattern'; +import { configMock } from '../../../__mocks__/config'; describe('Resolve index pattern tests', () => { test('returns valid data for an existing index pattern', async () => { diff --git a/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts b/src/plugins/discover/public/application/main/utils/resolve_index_pattern.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts rename to src/plugins/discover/public/application/main/utils/resolve_index_pattern.ts diff --git a/src/plugins/discover/public/application/apps/main/utils/update_search_source.test.ts b/src/plugins/discover/public/application/main/utils/update_search_source.test.ts similarity index 91% rename from src/plugins/discover/public/application/apps/main/utils/update_search_source.test.ts rename to src/plugins/discover/public/application/main/utils/update_search_source.test.ts index 22f3b6ad86f6c..3d36cf1cce5da 100644 --- a/src/plugins/discover/public/application/apps/main/utils/update_search_source.test.ts +++ b/src/plugins/discover/public/application/main/utils/update_search_source.test.ts @@ -7,10 +7,10 @@ */ import { updateSearchSource } from './update_search_source'; -import { createSearchSourceMock } from '../../../../../../data/common/search/search_source/mocks'; -import { indexPatternMock } from '../../../../__mocks__/index_pattern'; -import type { SortOrder } from '../../../../saved_searches'; -import { discoverServiceMock } from '../../../../__mocks__/services'; +import { createSearchSourceMock } from '../../../../../data/common/search/search_source/mocks'; +import { indexPatternMock } from '../../../__mocks__/index_pattern'; +import type { SortOrder } from '../../../services/saved_searches'; +import { discoverServiceMock } from '../../../__mocks__/services'; describe('updateSearchSource', () => { test('updates a given search source', async () => { diff --git a/src/plugins/discover/public/application/apps/main/utils/update_search_source.ts b/src/plugins/discover/public/application/main/utils/update_search_source.ts similarity index 85% rename from src/plugins/discover/public/application/apps/main/utils/update_search_source.ts rename to src/plugins/discover/public/application/main/utils/update_search_source.ts index 6d592e176afe5..a08f180f1816c 100644 --- a/src/plugins/discover/public/application/apps/main/utils/update_search_source.ts +++ b/src/plugins/discover/public/application/main/utils/update_search_source.ts @@ -6,11 +6,11 @@ * Side Public License, v 1. */ -import { SORT_DEFAULT_ORDER_SETTING } from '../../../../../common'; -import { IndexPattern, ISearchSource } from '../../../../../../data/common'; -import type { SortOrder } from '../../../../saved_searches'; -import { DiscoverServices } from '../../../../build_services'; -import { getSortForSearchSource } from '../components/doc_table'; +import { SORT_DEFAULT_ORDER_SETTING } from '../../../../common'; +import { IndexPattern, ISearchSource } from '../../../../../data/common'; +import type { SortOrder } from '../../../services/saved_searches'; +import { DiscoverServices } from '../../../build_services'; +import { getSortForSearchSource } from '../../../components/doc_table'; /** * Helper function to update the given searchSource before fetching/sharing/persisting diff --git a/src/plugins/discover/public/application/apps/main/utils/use_behavior_subject.ts b/src/plugins/discover/public/application/main/utils/use_behavior_subject.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/utils/use_behavior_subject.ts rename to src/plugins/discover/public/application/main/utils/use_behavior_subject.ts diff --git a/src/plugins/discover/public/application/apps/main/utils/use_data_state.ts b/src/plugins/discover/public/application/main/utils/use_data_state.ts similarity index 94% rename from src/plugins/discover/public/application/apps/main/utils/use_data_state.ts rename to src/plugins/discover/public/application/main/utils/use_data_state.ts index 2fd571a0dfcb9..7bfa4205081e9 100644 --- a/src/plugins/discover/public/application/apps/main/utils/use_data_state.ts +++ b/src/plugins/discover/public/application/main/utils/use_data_state.ts @@ -7,7 +7,7 @@ */ import { useState, useEffect } from 'react'; import { BehaviorSubject } from 'rxjs'; -import { DataMsg } from '../services/use_saved_search'; +import { DataMsg } from './use_saved_search'; export function useDataState(data$: BehaviorSubject) { const [fetchState, setFetchState] = useState(data$.getValue()); diff --git a/src/plugins/discover/public/application/apps/main/services/use_discover_state.test.ts b/src/plugins/discover/public/application/main/utils/use_discover_state.test.ts similarity index 87% rename from src/plugins/discover/public/application/apps/main/services/use_discover_state.test.ts rename to src/plugins/discover/public/application/main/utils/use_discover_state.test.ts index c719f83980aa0..78f742b9f7c9b 100644 --- a/src/plugins/discover/public/application/apps/main/services/use_discover_state.test.ts +++ b/src/plugins/discover/public/application/main/utils/use_discover_state.test.ts @@ -7,12 +7,12 @@ */ import { renderHook, act } from '@testing-library/react-hooks'; -import { createSearchSessionMock } from '../../../../__mocks__/search_session'; -import { discoverServiceMock } from '../../../../__mocks__/services'; -import { savedSearchMock } from '../../../../__mocks__/saved_search'; +import { createSearchSessionMock } from '../../../__mocks__/search_session'; +import { discoverServiceMock } from '../../../__mocks__/services'; +import { savedSearchMock } from '../../../__mocks__/saved_search'; import { useDiscoverState } from './use_discover_state'; -import { indexPatternMock } from '../../../../__mocks__/index_pattern'; -import { SearchSource } from '../../../../../../data/common'; +import { indexPatternMock } from '../../../__mocks__/index_pattern'; +import { SearchSource } from '../../../../../data/common'; describe('test useDiscoverState', () => { const originalSavedObjectsClient = discoverServiceMock.core.savedObjects.client; diff --git a/src/plugins/discover/public/application/apps/main/services/use_discover_state.ts b/src/plugins/discover/public/application/main/utils/use_discover_state.ts similarity index 93% rename from src/plugins/discover/public/application/apps/main/services/use_discover_state.ts rename to src/plugins/discover/public/application/main/utils/use_discover_state.ts index a1d58fdd6090e..b70bcded4c608 100644 --- a/src/plugins/discover/public/application/apps/main/services/use_discover_state.ts +++ b/src/plugins/discover/public/application/main/utils/use_discover_state.ts @@ -8,22 +8,22 @@ import { useMemo, useEffect, useState, useCallback } from 'react'; import { isEqual } from 'lodash'; import { History } from 'history'; -import { getState } from './discover_state'; -import { getStateDefaults } from '../utils/get_state_defaults'; -import { DiscoverServices } from '../../../../build_services'; -import { SavedSearch, getSavedSearch } from '../../../../saved_searches'; -import { loadIndexPattern } from '../utils/resolve_index_pattern'; +import { getState } from '../services/discover_state'; +import { getStateDefaults } from './get_state_defaults'; +import { DiscoverServices } from '../../../build_services'; +import { SavedSearch, getSavedSearch } from '../../../services/saved_searches'; +import { loadIndexPattern } from './resolve_index_pattern'; import { useSavedSearch as useSavedSearchData } from './use_saved_search'; import { MODIFY_COLUMNS_ON_SWITCH, SEARCH_FIELDS_FROM_SOURCE, SEARCH_ON_PAGE_LOAD_SETTING, SORT_DEFAULT_ORDER_SETTING, -} from '../../../../../common'; +} from '../../../../common'; import { useSearchSession } from './use_search_session'; -import { FetchStatus } from '../../../types'; -import { getSwitchIndexPatternAppState } from '../utils/get_switch_index_pattern_app_state'; -import { SortPairArr } from '../components/doc_table/lib/get_sort'; +import { FetchStatus } from '../../types'; +import { getSwitchIndexPatternAppState } from './get_switch_index_pattern_app_state'; +import { SortPairArr } from '../../../components/doc_table/lib/get_sort'; export function useDiscoverState({ services, diff --git a/src/plugins/discover/public/application/apps/main/services/use_saved_search.test.ts b/src/plugins/discover/public/application/main/utils/use_saved_search.test.ts similarity index 91% rename from src/plugins/discover/public/application/apps/main/services/use_saved_search.test.ts rename to src/plugins/discover/public/application/main/utils/use_saved_search.test.ts index 7f252151920fb..b3ed7ab854190 100644 --- a/src/plugins/discover/public/application/apps/main/services/use_saved_search.test.ts +++ b/src/plugins/discover/public/application/main/utils/use_saved_search.test.ts @@ -7,14 +7,14 @@ */ import { Subject } from 'rxjs'; import { renderHook } from '@testing-library/react-hooks'; -import { createSearchSessionMock } from '../../../../__mocks__/search_session'; -import { discoverServiceMock } from '../../../../__mocks__/services'; -import { savedSearchMock } from '../../../../__mocks__/saved_search'; +import { createSearchSessionMock } from '../../../__mocks__/search_session'; +import { discoverServiceMock } from '../../../__mocks__/services'; +import { savedSearchMock } from '../../../__mocks__/saved_search'; import { useSavedSearch } from './use_saved_search'; -import { getState } from './discover_state'; -import { uiSettingsMock } from '../../../../__mocks__/ui_settings'; +import { getState } from '../services/discover_state'; +import { uiSettingsMock } from '../../../__mocks__/ui_settings'; import { useDiscoverState } from './use_discover_state'; -import { FetchStatus } from '../../../types'; +import { FetchStatus } from '../../types'; describe('test useSavedSearch', () => { test('useSavedSearch return is valid', async () => { diff --git a/src/plugins/discover/public/application/apps/main/services/use_saved_search.ts b/src/plugins/discover/public/application/main/utils/use_saved_search.ts similarity index 88% rename from src/plugins/discover/public/application/apps/main/services/use_saved_search.ts rename to src/plugins/discover/public/application/main/utils/use_saved_search.ts index 6cadfbb89acfb..bfd6f1daa4bc0 100644 --- a/src/plugins/discover/public/application/apps/main/services/use_saved_search.ts +++ b/src/plugins/discover/public/application/main/utils/use_saved_search.ts @@ -7,22 +7,22 @@ */ import { useCallback, useEffect, useMemo, useRef } from 'react'; import { BehaviorSubject, Subject } from 'rxjs'; -import { DiscoverServices } from '../../../../build_services'; -import { DiscoverSearchSessionManager } from './discover_search_session'; -import { ISearchSource } from '../../../../../../data/common'; -import { GetStateReturn } from './discover_state'; -import { ElasticSearchHit } from '../../../doc_views/doc_views_types'; -import { RequestAdapter } from '../../../../../../inspector/public'; -import type { AutoRefreshDoneFn } from '../../../../../../data/public'; -import { validateTimeRange } from '../utils/validate_time_range'; +import { DiscoverServices } from '../../../build_services'; +import { DiscoverSearchSessionManager } from '../services/discover_search_session'; +import { ISearchSource } from '../../../../../data/common'; +import { GetStateReturn } from '../services/discover_state'; +import { ElasticSearchHit } from '../../../services/doc_views/doc_views_types'; +import { RequestAdapter } from '../../../../../inspector/public'; +import type { AutoRefreshDoneFn } from '../../../../../data/public'; +import { validateTimeRange } from './validate_time_range'; import { Chart } from '../components/chart/point_series'; -import { useSingleton } from '../utils/use_singleton'; -import { FetchStatus } from '../../../types'; +import { useSingleton } from './use_singleton'; +import { FetchStatus } from '../../types'; -import { fetchAll } from '../utils/fetch_all'; -import { useBehaviorSubject } from '../utils/use_behavior_subject'; +import { fetchAll } from './fetch_all'; +import { useBehaviorSubject } from './use_behavior_subject'; import { sendResetMsg } from './use_saved_search_messages'; -import { getFetch$ } from '../utils/get_fetch_observable'; +import { getFetch$ } from './get_fetch_observable'; export interface SavedSearchData { main$: DataMain$; diff --git a/src/plugins/discover/public/application/apps/main/services/use_saved_search_messages.test.ts b/src/plugins/discover/public/application/main/utils/use_saved_search_messages.test.ts similarity index 98% rename from src/plugins/discover/public/application/apps/main/services/use_saved_search_messages.test.ts rename to src/plugins/discover/public/application/main/utils/use_saved_search_messages.test.ts index 9810436aebd90..2fa264690329e 100644 --- a/src/plugins/discover/public/application/apps/main/services/use_saved_search_messages.test.ts +++ b/src/plugins/discover/public/application/main/utils/use_saved_search_messages.test.ts @@ -11,7 +11,7 @@ import { sendLoadingMsg, sendPartialMsg, } from './use_saved_search_messages'; -import { FetchStatus } from '../../../types'; +import { FetchStatus } from '../../types'; import { BehaviorSubject } from 'rxjs'; import { DataMainMsg } from './use_saved_search'; diff --git a/src/plugins/discover/public/application/apps/main/services/use_saved_search_messages.ts b/src/plugins/discover/public/application/main/utils/use_saved_search_messages.ts similarity index 98% rename from src/plugins/discover/public/application/apps/main/services/use_saved_search_messages.ts rename to src/plugins/discover/public/application/main/utils/use_saved_search_messages.ts index ff72a69e65fa8..325d63eb6d21a 100644 --- a/src/plugins/discover/public/application/apps/main/services/use_saved_search_messages.ts +++ b/src/plugins/discover/public/application/main/utils/use_saved_search_messages.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { FetchStatus } from '../../../types'; +import { FetchStatus } from '../../types'; import { DataCharts$, DataDocuments$, diff --git a/src/plugins/discover/public/application/apps/main/services/use_search_session.test.ts b/src/plugins/discover/public/application/main/utils/use_search_session.test.ts similarity index 77% rename from src/plugins/discover/public/application/apps/main/services/use_search_session.test.ts rename to src/plugins/discover/public/application/main/utils/use_search_session.test.ts index 8aa6e0764d8ec..bc9af1001aa77 100644 --- a/src/plugins/discover/public/application/apps/main/services/use_search_session.test.ts +++ b/src/plugins/discover/public/application/main/utils/use_search_session.test.ts @@ -8,11 +8,11 @@ import { useSearchSession } from './use_search_session'; import { renderHook } from '@testing-library/react-hooks'; -import { createSearchSessionMock } from '../../../../__mocks__/search_session'; -import { discoverServiceMock } from '../../../../__mocks__/services'; -import { savedSearchMock } from '../../../../__mocks__/saved_search'; -import { getState } from './discover_state'; -import { uiSettingsMock } from '../../../../__mocks__/ui_settings'; +import { createSearchSessionMock } from '../../../__mocks__/search_session'; +import { discoverServiceMock } from '../../../__mocks__/services'; +import { savedSearchMock } from '../../../__mocks__/saved_search'; +import { getState } from '../services/discover_state'; +import { uiSettingsMock } from '../../../__mocks__/ui_settings'; describe('test useSearchSession', () => { test('getting the next session id', async () => { diff --git a/src/plugins/discover/public/application/apps/main/services/use_search_session.ts b/src/plugins/discover/public/application/main/utils/use_search_session.ts similarity index 82% rename from src/plugins/discover/public/application/apps/main/services/use_search_session.ts rename to src/plugins/discover/public/application/main/utils/use_search_session.ts index e37e8f6f33839..c18261f1ffaac 100644 --- a/src/plugins/discover/public/application/apps/main/services/use_search_session.ts +++ b/src/plugins/discover/public/application/main/utils/use_search_session.ts @@ -7,11 +7,14 @@ */ import { useMemo, useEffect } from 'react'; import { History } from 'history'; -import { DiscoverSearchSessionManager } from './discover_search_session'; -import { createSearchSessionRestorationDataProvider, GetStateReturn } from './discover_state'; -import { noSearchSessionStorageCapabilityMessage } from '../../../../../../data/public'; -import { DiscoverServices } from '../../../../build_services'; -import { SavedSearch } from '../../../../saved_searches'; +import { DiscoverSearchSessionManager } from '../services/discover_search_session'; +import { + createSearchSessionRestorationDataProvider, + GetStateReturn, +} from '../services/discover_state'; +import { noSearchSessionStorageCapabilityMessage } from '../../../../../data/public'; +import { DiscoverServices } from '../../../build_services'; +import { SavedSearch } from '../../../services/saved_searches'; export function useSearchSession({ services, diff --git a/src/plugins/discover/public/application/apps/main/utils/use_singleton.ts b/src/plugins/discover/public/application/main/utils/use_singleton.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/utils/use_singleton.ts rename to src/plugins/discover/public/application/main/utils/use_singleton.ts diff --git a/src/plugins/discover/public/application/apps/main/services/use_url.test.ts b/src/plugins/discover/public/application/main/utils/use_url.test.ts similarity index 92% rename from src/plugins/discover/public/application/apps/main/services/use_url.test.ts rename to src/plugins/discover/public/application/main/utils/use_url.test.ts index 740ca2bd140d7..9d8191f3581e4 100644 --- a/src/plugins/discover/public/application/apps/main/services/use_url.test.ts +++ b/src/plugins/discover/public/application/main/utils/use_url.test.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ import { renderHook } from '@testing-library/react-hooks'; -import { createSearchSessionMock } from '../../../../__mocks__/search_session'; +import { createSearchSessionMock } from '../../../__mocks__/search_session'; import { useUrl } from './use_url'; describe('test useUrl', () => { diff --git a/src/plugins/discover/public/application/apps/main/services/use_url.ts b/src/plugins/discover/public/application/main/utils/use_url.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/services/use_url.ts rename to src/plugins/discover/public/application/main/utils/use_url.ts diff --git a/src/plugins/discover/public/application/apps/main/utils/validate_time_range.test.ts b/src/plugins/discover/public/application/main/utils/validate_time_range.test.ts similarity index 94% rename from src/plugins/discover/public/application/apps/main/utils/validate_time_range.test.ts rename to src/plugins/discover/public/application/main/utils/validate_time_range.test.ts index 8d9d9adc4e8dc..ff3a66b1edfa3 100644 --- a/src/plugins/discover/public/application/apps/main/utils/validate_time_range.test.ts +++ b/src/plugins/discover/public/application/main/utils/validate_time_range.test.ts @@ -7,7 +7,7 @@ */ import { validateTimeRange } from './validate_time_range'; -import { notificationServiceMock } from '../../../../../../../core/public/mocks'; +import { notificationServiceMock } from '../../../../../../core/public/mocks'; describe('Discover validateTimeRange', () => { test('validates given time ranges correctly', async () => { diff --git a/src/plugins/discover/public/application/apps/main/utils/validate_time_range.ts b/src/plugins/discover/public/application/main/utils/validate_time_range.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/utils/validate_time_range.ts rename to src/plugins/discover/public/application/main/utils/validate_time_range.ts diff --git a/src/plugins/discover/public/application/apps/not_found/index.ts b/src/plugins/discover/public/application/not_found/index.ts similarity index 100% rename from src/plugins/discover/public/application/apps/not_found/index.ts rename to src/plugins/discover/public/application/not_found/index.ts diff --git a/src/plugins/discover/public/application/apps/not_found/not_found_route.tsx b/src/plugins/discover/public/application/not_found/not_found_route.tsx similarity index 92% rename from src/plugins/discover/public/application/apps/not_found/not_found_route.tsx rename to src/plugins/discover/public/application/not_found/not_found_route.tsx index 6b6ef584d07f1..4848248a7509d 100644 --- a/src/plugins/discover/public/application/apps/not_found/not_found_route.tsx +++ b/src/plugins/discover/public/application/not_found/not_found_route.tsx @@ -10,9 +10,9 @@ import { i18n } from '@kbn/i18n'; import { EuiCallOut } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { Redirect } from 'react-router-dom'; -import { toMountPoint } from '../../../../../kibana_react/public'; -import { DiscoverServices } from '../../../build_services'; -import { getUrlTracker } from '../../../kibana_services'; +import { toMountPoint } from '../../../../kibana_react/public'; +import { DiscoverServices } from '../../build_services'; +import { getUrlTracker } from '../../kibana_services'; export interface NotFoundRouteProps { /** diff --git a/src/plugins/discover/public/application/components/common/__snapshots__/loading_indicator.test.tsx.snap b/src/plugins/discover/public/components/common/__snapshots__/loading_indicator.test.tsx.snap similarity index 100% rename from src/plugins/discover/public/application/components/common/__snapshots__/loading_indicator.test.tsx.snap rename to src/plugins/discover/public/components/common/__snapshots__/loading_indicator.test.tsx.snap diff --git a/src/plugins/discover/public/shared/components.tsx b/src/plugins/discover/public/components/common/deferred_spinner.tsx similarity index 100% rename from src/plugins/discover/public/shared/components.tsx rename to src/plugins/discover/public/components/common/deferred_spinner.tsx diff --git a/src/plugins/discover/public/application/components/common/loading_indicator.test.tsx b/src/plugins/discover/public/components/common/loading_indicator.test.tsx similarity index 100% rename from src/plugins/discover/public/application/components/common/loading_indicator.test.tsx rename to src/plugins/discover/public/components/common/loading_indicator.test.tsx diff --git a/src/plugins/discover/public/application/components/common/loading_indicator.tsx b/src/plugins/discover/public/components/common/loading_indicator.tsx similarity index 100% rename from src/plugins/discover/public/application/components/common/loading_indicator.tsx rename to src/plugins/discover/public/components/common/loading_indicator.tsx diff --git a/src/plugins/discover/public/application/components/data_visualizer_grid/data_visualizer_grid.tsx b/src/plugins/discover/public/components/data_visualizer_grid/data_visualizer_grid.tsx similarity index 95% rename from src/plugins/discover/public/application/components/data_visualizer_grid/data_visualizer_grid.tsx rename to src/plugins/discover/public/components/data_visualizer_grid/data_visualizer_grid.tsx index 5492fac014b74..511aa90f5f4a4 100644 --- a/src/plugins/discover/public/application/components/data_visualizer_grid/data_visualizer_grid.tsx +++ b/src/plugins/discover/public/components/data_visualizer_grid/data_visualizer_grid.tsx @@ -8,17 +8,17 @@ import React, { useEffect, useMemo, useRef, useState } from 'react'; import { Filter } from '@kbn/es-query'; -import { IndexPatternField, IndexPattern, DataView, Query } from '../../../../../data/common'; -import { DiscoverServices } from '../../../build_services'; +import { IndexPatternField, IndexPattern, DataView, Query } from '../../../../data/common'; +import { DiscoverServices } from '../../build_services'; import { EmbeddableInput, EmbeddableOutput, ErrorEmbeddable, IEmbeddable, isErrorEmbeddable, -} from '../../../../../embeddable/public'; -import { SavedSearch } from '../../../saved_searches'; -import { GetStateReturn } from '../../apps/main/services/discover_state'; +} from '../../../../embeddable/public'; +import { SavedSearch } from '../../services/saved_searches'; +import { GetStateReturn } from '../../application/main/services/discover_state'; export interface DataVisualizerGridEmbeddableInput extends EmbeddableInput { indexPattern: IndexPattern; diff --git a/src/plugins/discover/public/application/components/data_visualizer_grid/field_stats_table_embeddable.tsx b/src/plugins/discover/public/components/data_visualizer_grid/field_stats_table_embeddable.tsx similarity index 100% rename from src/plugins/discover/public/application/components/data_visualizer_grid/field_stats_table_embeddable.tsx rename to src/plugins/discover/public/components/data_visualizer_grid/field_stats_table_embeddable.tsx diff --git a/src/plugins/discover/public/application/components/data_visualizer_grid/index.ts b/src/plugins/discover/public/components/data_visualizer_grid/index.ts similarity index 100% rename from src/plugins/discover/public/application/components/data_visualizer_grid/index.ts rename to src/plugins/discover/public/components/data_visualizer_grid/index.ts diff --git a/src/plugins/discover/public/application/components/discover_grid/constants.ts b/src/plugins/discover/public/components/discover_grid/constants.ts similarity index 100% rename from src/plugins/discover/public/application/components/discover_grid/constants.ts rename to src/plugins/discover/public/components/discover_grid/constants.ts diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid.scss b/src/plugins/discover/public/components/discover_grid/discover_grid.scss similarity index 100% rename from src/plugins/discover/public/application/components/discover_grid/discover_grid.scss rename to src/plugins/discover/public/components/discover_grid/discover_grid.scss diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid.test.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid.test.tsx similarity index 92% rename from src/plugins/discover/public/application/components/discover_grid/discover_grid.test.tsx rename to src/plugins/discover/public/components/discover_grid/discover_grid.test.tsx index 22284480afc05..4a0e472f17455 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid.test.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid.test.tsx @@ -10,18 +10,18 @@ import { ReactWrapper } from 'enzyme'; import { EuiCopy } from '@elastic/eui'; import { act } from 'react-dom/test-utils'; import { findTestSubject } from '@elastic/eui/lib/test'; -import { esHits } from '../../../__mocks__/es_hits'; -import { indexPatternMock } from '../../../__mocks__/index_pattern'; +import { esHits } from '../../__mocks__/es_hits'; +import { indexPatternMock } from '../../__mocks__/index_pattern'; import { mountWithIntl } from '@kbn/test/jest'; import { DiscoverGrid, DiscoverGridProps } from './discover_grid'; -import { uiSettingsMock } from '../../../__mocks__/ui_settings'; -import { DiscoverServices } from '../../../build_services'; -import { ElasticSearchHit } from '../../doc_views/doc_views_types'; +import { uiSettingsMock } from '../../__mocks__/ui_settings'; +import { DiscoverServices } from '../../build_services'; +import { ElasticSearchHit } from '../../services/doc_views/doc_views_types'; import { getDocId } from './discover_grid_document_selection'; -jest.mock('../../../kibana_services', () => ({ - ...jest.requireActual('../../../kibana_services'), - getServices: () => jest.requireActual('../../../__mocks__/services').discoverServiceMock, +jest.mock('../../kibana_services', () => ({ + ...jest.requireActual('../../kibana_services'), + getServices: () => jest.requireActual('../../__mocks__/services').discoverServiceMock, })); function getProps() { diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid.tsx similarity index 96% rename from src/plugins/discover/public/application/components/discover_grid/discover_grid.tsx rename to src/plugins/discover/public/components/discover_grid/discover_grid.tsx index 6f96f21c9b8c8..9bcc0f90f9259 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid.tsx @@ -21,8 +21,8 @@ import { EuiLoadingSpinner, EuiIcon, } from '@elastic/eui'; -import { flattenHit, IndexPattern } from '../../../../../data/common'; -import { DocViewFilterFn, ElasticSearchHit } from '../../doc_views/doc_views_types'; +import { flattenHit, IndexPattern } from '../../../../data/common'; +import { DocViewFilterFn, ElasticSearchHit } from '../../services/doc_views/doc_views_types'; import { getSchemaDetectors } from './discover_grid_schema'; import { DiscoverGridFlyout } from './discover_grid_flyout'; import { DiscoverGridContext } from './discover_grid_context'; @@ -34,16 +34,16 @@ import { getVisibleColumns, } from './discover_grid_columns'; import { defaultPageSize, gridStyle, pageSizeArr, toolbarVisibility } from './constants'; -import { DiscoverServices } from '../../../build_services'; -import { getDisplayedColumns } from '../../helpers/columns'; +import { DiscoverServices } from '../../build_services'; +import { getDisplayedColumns } from '../../utils/columns'; import { DOC_HIDE_TIME_COLUMN_SETTING, MAX_DOC_FIELDS_DISPLAYED, SHOW_MULTIFIELDS, -} from '../../../../common'; +} from '../../../common'; import { DiscoverGridDocumentToolbarBtn, getDocId } from './discover_grid_document_selection'; -import { SortPairArr } from '../../apps/main/components/doc_table/lib/get_sort'; -import { getFieldsToShow } from '../../helpers/get_fields_to_show'; +import { SortPairArr } from '../doc_table/lib/get_sort'; +import { getFieldsToShow } from '../../utils/get_fields_to_show'; interface SortObj { id: string; diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.test.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid_cell_actions.test.tsx similarity index 95% rename from src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.test.tsx rename to src/plugins/discover/public/components/discover_grid/discover_grid_cell_actions.test.tsx index de3c55ad7a869..736175c04d3c2 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.test.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid_cell_actions.test.tsx @@ -12,8 +12,8 @@ import { findTestSubject } from '@elastic/eui/lib/test'; import { FilterInBtn, FilterOutBtn, buildCellActions } from './discover_grid_cell_actions'; import { DiscoverGridContext } from './discover_grid_context'; -import { indexPatternMock } from '../../../__mocks__/index_pattern'; -import { esHits } from '../../../__mocks__/es_hits'; +import { indexPatternMock } from '../../__mocks__/index_pattern'; +import { esHits } from '../../__mocks__/es_hits'; import { EuiButton } from '@elastic/eui'; import { IndexPatternField } from 'src/plugins/data/common'; diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid_cell_actions.tsx similarity index 96% rename from src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx rename to src/plugins/discover/public/components/discover_grid/discover_grid_cell_actions.tsx index a31b551821ddb..41852afe7b32c 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid_cell_actions.tsx @@ -9,7 +9,7 @@ import React, { useContext } from 'react'; import { EuiDataGridColumnCellActionProps } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { flattenHit, IndexPatternField } from '../../../../../data/common'; +import { flattenHit, IndexPatternField } from '../../../../data/common'; import { DiscoverGridContext } from './discover_grid_context'; export const FilterInBtn = ({ diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.test.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid_columns.test.tsx similarity index 96% rename from src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.test.tsx rename to src/plugins/discover/public/components/discover_grid/discover_grid_columns.test.tsx index e5ea657032403..ea9cd5034551e 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.test.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid_columns.test.tsx @@ -6,9 +6,9 @@ * Side Public License, v 1. */ -import { indexPatternMock } from '../../../__mocks__/index_pattern'; +import { indexPatternMock } from '../../__mocks__/index_pattern'; import { getEuiGridColumns } from './discover_grid_columns'; -import { indexPatternWithTimefieldMock } from '../../../__mocks__/index_pattern_with_timefield'; +import { indexPatternWithTimefieldMock } from '../../__mocks__/index_pattern_with_timefield'; describe('Discover grid columns ', function () { it('returns eui grid columns without time column', async () => { diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid_columns.tsx similarity index 98% rename from src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx rename to src/plugins/discover/public/components/discover_grid/discover_grid_columns.tsx index 5eb55a8e99cde..872fa3133a024 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid_columns.tsx @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { EuiDataGridColumn, EuiIconTip, EuiScreenReaderOnly } from '@elastic/eui'; import { ExpandButton } from './discover_grid_expand_button'; import { DiscoverGridSettings } from './types'; -import type { IndexPattern } from '../../../../../data/common'; +import type { IndexPattern } from '../../../../data/common'; import { buildCellActions } from './discover_grid_cell_actions'; import { getSchemaByKbnType } from './discover_grid_schema'; import { SelectButton } from './discover_grid_document_selection'; diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid_context.tsx similarity index 90% rename from src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx rename to src/plugins/discover/public/components/discover_grid/discover_grid_context.tsx index 8d0fbec9d7933..49b72ef126a76 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid_context.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { IndexPattern } from 'src/plugins/data/common'; -import { DocViewFilterFn, ElasticSearchHit } from '../../doc_views/doc_views_types'; +import { DocViewFilterFn, ElasticSearchHit } from '../../services/doc_views/doc_views_types'; export interface GridContext { expanded: ElasticSearchHit | undefined; diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_document_selection.test.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid_document_selection.test.tsx similarity index 97% rename from src/plugins/discover/public/application/components/discover_grid/discover_grid_document_selection.test.tsx rename to src/plugins/discover/public/components/discover_grid/discover_grid_document_selection.test.tsx index e9b93e21553a2..d57fba241a1e7 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_document_selection.test.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid_document_selection.test.tsx @@ -13,8 +13,8 @@ import { getDocId, SelectButton, } from './discover_grid_document_selection'; -import { esHits } from '../../../__mocks__/es_hits'; -import { indexPatternMock } from '../../../__mocks__/index_pattern'; +import { esHits } from '../../__mocks__/es_hits'; +import { indexPatternMock } from '../../__mocks__/index_pattern'; import { DiscoverGridContext } from './discover_grid_context'; const baseContextMock = { diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_document_selection.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid_document_selection.tsx similarity index 98% rename from src/plugins/discover/public/application/components/discover_grid/discover_grid_document_selection.tsx rename to src/plugins/discover/public/components/discover_grid/discover_grid_document_selection.tsx index c87d425d601c5..abf63d2fe76b0 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_document_selection.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid_document_selection.tsx @@ -19,7 +19,7 @@ import { import { FormattedMessage } from '@kbn/i18n/react'; import themeDark from '@elastic/eui/dist/eui_theme_dark.json'; import themeLight from '@elastic/eui/dist/eui_theme_light.json'; -import { ElasticSearchHit } from '../../doc_views/doc_views_types'; +import { ElasticSearchHit } from '../../services/doc_views/doc_views_types'; import { DiscoverGridContext } from './discover_grid_context'; /** diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_expand_button.test.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid_expand_button.test.tsx similarity index 96% rename from src/plugins/discover/public/application/components/discover_grid/discover_grid_expand_button.test.tsx rename to src/plugins/discover/public/components/discover_grid/discover_grid_expand_button.test.tsx index 3f7cb70091cfa..de2117afe7bdb 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_expand_button.test.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid_expand_button.test.tsx @@ -11,8 +11,8 @@ import { mountWithIntl } from '@kbn/test/jest'; import { findTestSubject } from '@elastic/eui/lib/test'; import { ExpandButton } from './discover_grid_expand_button'; import { DiscoverGridContext } from './discover_grid_context'; -import { indexPatternMock } from '../../../__mocks__/index_pattern'; -import { esHits } from '../../../__mocks__/es_hits'; +import { indexPatternMock } from '../../__mocks__/index_pattern'; +import { esHits } from '../../__mocks__/es_hits'; const baseContextMock = { expanded: undefined, diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_expand_button.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid_expand_button.tsx similarity index 97% rename from src/plugins/discover/public/application/components/discover_grid/discover_grid_expand_button.tsx rename to src/plugins/discover/public/components/discover_grid/discover_grid_expand_button.tsx index f259d5c5c3658..1a7080b9613d0 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_expand_button.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid_expand_button.tsx @@ -12,7 +12,7 @@ import themeDark from '@elastic/eui/dist/eui_theme_dark.json'; import themeLight from '@elastic/eui/dist/eui_theme_light.json'; import { i18n } from '@kbn/i18n'; import { DiscoverGridContext } from './discover_grid_context'; -import { EsHitRecord } from '../../types'; +import { EsHitRecord } from '../../application/types'; /** * Button to expand a given row */ diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.test.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid_flyout.test.tsx similarity index 93% rename from src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.test.tsx rename to src/plugins/discover/public/components/discover_grid/discover_grid_flyout.test.tsx index 83fa447a50ba0..64e97b824a2f9 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.test.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid_flyout.test.tsx @@ -10,13 +10,13 @@ import React from 'react'; import { findTestSubject } from '@elastic/eui/lib/test'; import { mountWithIntl } from '@kbn/test/jest'; import { DiscoverGridFlyout } from './discover_grid_flyout'; -import { esHits } from '../../../__mocks__/es_hits'; -import { createFilterManagerMock } from '../../../../../data/public/query/filter_manager/filter_manager.mock'; -import { indexPatternMock } from '../../../__mocks__/index_pattern'; -import { DiscoverServices } from '../../../build_services'; -import { DocViewsRegistry } from '../../doc_views/doc_views_registry'; -import { setDocViewsRegistry } from '../../../kibana_services'; -import { indexPatternWithTimefieldMock } from '../../../__mocks__/index_pattern_with_timefield'; +import { esHits } from '../../__mocks__/es_hits'; +import { createFilterManagerMock } from '../../../../data/public/query/filter_manager/filter_manager.mock'; +import { indexPatternMock } from '../../__mocks__/index_pattern'; +import { DiscoverServices } from '../../build_services'; +import { DocViewsRegistry } from '../../services/doc_views/doc_views_registry'; +import { setDocViewsRegistry } from '../../kibana_services'; +import { indexPatternWithTimefieldMock } from '../../__mocks__/index_pattern_with_timefield'; describe('Discover flyout', function () { setDocViewsRegistry(new DocViewsRegistry()); diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid_flyout.tsx similarity index 95% rename from src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx rename to src/plugins/discover/public/components/discover_grid/discover_grid_flyout.tsx index f6e5e25f284ca..d5b2248162b2f 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid_flyout.tsx @@ -24,11 +24,11 @@ import { EuiHideFor, keys, } from '@elastic/eui'; -import { DocViewer } from '../doc_viewer/doc_viewer'; -import { DocViewFilterFn, ElasticSearchHit } from '../../doc_views/doc_views_types'; -import { DiscoverServices } from '../../../build_services'; -import { getContextUrl } from '../../helpers/get_context_url'; -import { getSingleDocUrl } from '../../helpers/get_single_doc_url'; +import { DocViewer } from '../../services/doc_views/components/doc_viewer/doc_viewer'; +import { DocViewFilterFn, ElasticSearchHit } from '../../services/doc_views/doc_views_types'; +import { DiscoverServices } from '../../build_services'; +import { getContextUrl } from '../../utils/get_context_url'; +import { getSingleDocUrl } from '../../utils/get_single_doc_url'; interface Props { columns: string[]; diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_schema.ts b/src/plugins/discover/public/components/discover_grid/discover_grid_schema.ts similarity index 94% rename from src/plugins/discover/public/application/components/discover_grid/discover_grid_schema.ts rename to src/plugins/discover/public/components/discover_grid/discover_grid_schema.ts index 0aa6dadd633e0..5cf257fb16f2c 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_schema.ts +++ b/src/plugins/discover/public/components/discover_grid/discover_grid_schema.ts @@ -7,7 +7,7 @@ */ import { kibanaJSON } from './constants'; -import { KBN_FIELD_TYPES } from '../../../../../data/common'; +import { KBN_FIELD_TYPES } from '../../../../data/common'; export function getSchemaByKbnType(kbnType: string | undefined) { // Default DataGrid schemas: boolean, numeric, datetime, json, currency, string diff --git a/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.test.tsx b/src/plugins/discover/public/components/discover_grid/get_render_cell_value.test.tsx similarity index 98% rename from src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.test.tsx rename to src/plugins/discover/public/components/discover_grid/get_render_cell_value.test.tsx index 3fb96ba9e9daa..260cbf42c4d8e 100644 --- a/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.test.tsx +++ b/src/plugins/discover/public/components/discover_grid/get_render_cell_value.test.tsx @@ -9,18 +9,18 @@ import React from 'react'; import { ReactWrapper, shallow } from 'enzyme'; import { getRenderCellValueFn } from './get_render_cell_value'; -import { indexPatternMock } from '../../../__mocks__/index_pattern'; -import { ElasticSearchHit } from '../../doc_views/doc_views_types'; +import { indexPatternMock } from '../../__mocks__/index_pattern'; +import { ElasticSearchHit } from '../../services/doc_views/doc_views_types'; import { flattenHit } from 'src/plugins/data/common'; -jest.mock('../../../../../kibana_react/public', () => ({ +jest.mock('../../../../kibana_react/public', () => ({ useUiSetting: () => true, withKibana: (comp: ReactWrapper) => { return comp; }, })); -jest.mock('../../../kibana_services', () => ({ +jest.mock('../../kibana_services', () => ({ getServices: () => ({ uiSettings: { get: jest.fn(), diff --git a/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx b/src/plugins/discover/public/components/discover_grid/get_render_cell_value.tsx similarity index 96% rename from src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx rename to src/plugins/discover/public/components/discover_grid/get_render_cell_value.tsx index 4066c13f6391e..bf7aaac1a86a2 100644 --- a/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx +++ b/src/plugins/discover/public/components/discover_grid/get_render_cell_value.tsx @@ -17,13 +17,13 @@ import { EuiDescriptionListTitle, EuiDescriptionListDescription, } from '@elastic/eui'; -import { ElasticSearchHit } from '../../doc_views/doc_views_types'; +import { ElasticSearchHit } from '../../services/doc_views/doc_views_types'; import { DiscoverGridContext } from './discover_grid_context'; import { JsonCodeEditor } from '../json_code_editor/json_code_editor'; import { defaultMonacoEditorWidth } from './constants'; -import { EsHitRecord } from '../../types'; -import { formatFieldValue } from '../../helpers/format_value'; -import { formatHit } from '../../helpers/format_hit'; +import { EsHitRecord } from '../../application/types'; +import { formatFieldValue } from '../../utils/format_value'; +import { formatHit } from '../../utils/format_hit'; export const getRenderCellValueFn = ( diff --git a/src/plugins/discover/public/application/components/discover_grid/types.ts b/src/plugins/discover/public/components/discover_grid/types.ts similarity index 100% rename from src/plugins/discover/public/application/components/discover_grid/types.ts rename to src/plugins/discover/public/components/discover_grid/types.ts diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/_doc_table.scss b/src/plugins/discover/public/components/doc_table/_doc_table.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/_doc_table.scss rename to src/plugins/discover/public/components/doc_table/_doc_table.scss diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/actions/columns.test.ts b/src/plugins/discover/public/components/doc_table/actions/columns.test.ts similarity index 86% rename from src/plugins/discover/public/application/apps/main/components/doc_table/actions/columns.test.ts rename to src/plugins/discover/public/components/doc_table/actions/columns.test.ts index 93b38cfc6519c..5f3c7d203122f 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/actions/columns.test.ts +++ b/src/plugins/discover/public/components/doc_table/actions/columns.test.ts @@ -7,11 +7,11 @@ */ import { getStateColumnActions } from './columns'; -import { configMock } from '../../../../../../__mocks__/config'; -import { indexPatternMock } from '../../../../../../__mocks__/index_pattern'; -import { indexPatternsMock } from '../../../../../../__mocks__/index_patterns'; -import { Capabilities } from '../../../../../../../../../core/types'; -import { AppState } from '../../../services/discover_state'; +import { configMock } from '../../../__mocks__/config'; +import { indexPatternMock } from '../../../__mocks__/index_pattern'; +import { indexPatternsMock } from '../../../__mocks__/index_patterns'; +import { Capabilities } from '../../../../../../core/types'; +import { AppState } from '../../../application/main/services/discover_state'; function getStateColumnAction(state: {}, setAppState: (state: Partial) => void) { return getStateColumnActions({ diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/actions/columns.ts b/src/plugins/discover/public/components/doc_table/actions/columns.ts similarity index 93% rename from src/plugins/discover/public/application/apps/main/components/doc_table/actions/columns.ts rename to src/plugins/discover/public/components/doc_table/actions/columns.ts index 2fc82e25634bd..cb771cc2c6de3 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/actions/columns.ts +++ b/src/plugins/discover/public/components/doc_table/actions/columns.ts @@ -6,17 +6,17 @@ * Side Public License, v 1. */ import { Capabilities, IUiSettingsClient } from 'kibana/public'; -import { SORT_DEFAULT_ORDER_SETTING } from '../../../../../../../common'; +import { SORT_DEFAULT_ORDER_SETTING } from '../../../../common'; import { AppState as DiscoverState, GetStateReturn as DiscoverGetStateReturn, -} from '../../../../../../application/apps/main/services/discover_state'; +} from '../../../application/main/services/discover_state'; import { AppState as ContextState, GetStateReturn as ContextGetStateReturn, -} from '../../../../context/services/context_state'; -import { IndexPattern, IndexPatternsContract } from '../../../../../../../../data/public'; -import { popularizeField } from '../../../../../helpers/popularize_field'; +} from '../../../application/context/services/context_state'; +import { IndexPattern, IndexPatternsContract } from '../../../../../data/public'; +import { popularizeField } from '../../../utils/popularize_field'; /** * Helper function to provide a fallback to a single _source column if the given array of columns diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/_index.scss b/src/plugins/discover/public/components/doc_table/components/_index.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/_index.scss rename to src/plugins/discover/public/components/doc_table/components/_index.scss diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/_table_header.scss b/src/plugins/discover/public/components/doc_table/components/_table_header.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/_table_header.scss rename to src/plugins/discover/public/components/doc_table/components/_table_header.scss diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/pager/tool_bar_pagination.tsx b/src/plugins/discover/public/components/doc_table/components/pager/tool_bar_pagination.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/pager/tool_bar_pagination.tsx rename to src/plugins/discover/public/components/doc_table/components/pager/tool_bar_pagination.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/__snapshots__/table_header.test.tsx.snap b/src/plugins/discover/public/components/doc_table/components/table_header/__snapshots__/table_header.test.tsx.snap similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/__snapshots__/table_header.test.tsx.snap rename to src/plugins/discover/public/components/doc_table/components/table_header/__snapshots__/table_header.test.tsx.snap diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx b/src/plugins/discover/public/components/doc_table/components/table_header/helpers.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx rename to src/plugins/discover/public/components/doc_table/components/table_header/helpers.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/score_sort_warning.tsx b/src/plugins/discover/public/components/doc_table/components/table_header/score_sort_warning.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/score_sort_warning.tsx rename to src/plugins/discover/public/components/doc_table/components/table_header/score_sort_warning.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/table_header.test.tsx b/src/plugins/discover/public/components/doc_table/components/table_header/table_header.test.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/table_header.test.tsx rename to src/plugins/discover/public/components/doc_table/components/table_header/table_header.test.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/table_header.tsx b/src/plugins/discover/public/components/doc_table/components/table_header/table_header.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/table_header.tsx rename to src/plugins/discover/public/components/doc_table/components/table_header/table_header.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/table_header_column.tsx b/src/plugins/discover/public/components/doc_table/components/table_header/table_header_column.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/table_header_column.tsx rename to src/plugins/discover/public/components/doc_table/components/table_header/table_header_column.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.test.tsx b/src/plugins/discover/public/components/doc_table/components/table_row.test.tsx similarity index 85% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.test.tsx rename to src/plugins/discover/public/components/doc_table/components/table_row.test.tsx index 887564168ac85..7b0e4d821af65 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.test.tsx +++ b/src/plugins/discover/public/components/doc_table/components/table_row.test.tsx @@ -9,12 +9,12 @@ import React from 'react'; import { mountWithIntl, findTestSubject } from '@kbn/test/jest'; import { TableRow, TableRowProps } from './table_row'; -import { setDocViewsRegistry, setServices } from '../../../../../../kibana_services'; -import { createFilterManagerMock } from '../../../../../../../../data/public/query/filter_manager/filter_manager.mock'; -import { DiscoverServices } from '../../../../../../build_services'; -import { indexPatternWithTimefieldMock } from '../../../../../../__mocks__/index_pattern_with_timefield'; -import { uiSettingsMock } from '../../../../../../__mocks__/ui_settings'; -import { DocViewsRegistry } from '../../../../../doc_views/doc_views_registry'; +import { setDocViewsRegistry, setServices } from '../../../kibana_services'; +import { createFilterManagerMock } from '../../../../../data/public/query/filter_manager/filter_manager.mock'; +import { DiscoverServices } from '../../../build_services'; +import { indexPatternWithTimefieldMock } from '../../../__mocks__/index_pattern_with_timefield'; +import { uiSettingsMock } from '../../../__mocks__/ui_settings'; +import { DocViewsRegistry } from '../../../services/doc_views/doc_views_registry'; jest.mock('../lib/row_formatter', () => { const originalModule = jest.requireActual('../lib/row_formatter'); diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx b/src/plugins/discover/public/components/doc_table/components/table_row.tsx similarity index 92% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx rename to src/plugins/discover/public/components/doc_table/components/table_row.tsx index 515782ce23f45..8a980cc4160d8 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx +++ b/src/plugins/discover/public/components/doc_table/components/table_row.tsx @@ -10,14 +10,14 @@ import React, { Fragment, useCallback, useMemo, useState } from 'react'; import classNames from 'classnames'; import { i18n } from '@kbn/i18n'; import { EuiButtonEmpty, EuiIcon } from '@elastic/eui'; -import { formatFieldValue } from '../../../../../helpers/format_value'; -import { flattenHit } from '../../../../../../../../data/common'; -import { DocViewer } from '../../../../../components/doc_viewer/doc_viewer'; -import { FilterManager, IndexPattern } from '../../../../../../../../data/public'; +import { formatFieldValue } from '../../../utils/format_value'; +import { flattenHit } from '../../../../../data/common'; +import { DocViewer } from '../../../services/doc_views/components/doc_viewer/doc_viewer'; +import { FilterManager, IndexPattern } from '../../../../../data/public'; import { TableCell } from './table_row/table_cell'; -import { ElasticSearchHit, DocViewFilterFn } from '../../../../../doc_views/doc_views_types'; -import { getContextUrl } from '../../../../../helpers/get_context_url'; -import { getSingleDocUrl } from '../../../../../helpers/get_single_doc_url'; +import { ElasticSearchHit, DocViewFilterFn } from '../../../services/doc_views/doc_views_types'; +import { getContextUrl } from '../../../utils/get_context_url'; +import { getSingleDocUrl } from '../../../utils/get_single_doc_url'; import { TableRowDetails } from './table_row_details'; import { formatRow, formatTopLevelObject } from '../lib/row_formatter'; diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row/__snapshots__/table_cell.test.tsx.snap b/src/plugins/discover/public/components/doc_table/components/table_row/__snapshots__/table_cell.test.tsx.snap similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row/__snapshots__/table_cell.test.tsx.snap rename to src/plugins/discover/public/components/doc_table/components/table_row/__snapshots__/table_cell.test.tsx.snap diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row/_cell.scss b/src/plugins/discover/public/components/doc_table/components/table_row/_cell.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row/_cell.scss rename to src/plugins/discover/public/components/doc_table/components/table_row/_cell.scss diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row/_details.scss b/src/plugins/discover/public/components/doc_table/components/table_row/_details.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row/_details.scss rename to src/plugins/discover/public/components/doc_table/components/table_row/_details.scss diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row/_index.scss b/src/plugins/discover/public/components/doc_table/components/table_row/_index.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row/_index.scss rename to src/plugins/discover/public/components/doc_table/components/table_row/_index.scss diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row/_open.scss b/src/plugins/discover/public/components/doc_table/components/table_row/_open.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row/_open.scss rename to src/plugins/discover/public/components/doc_table/components/table_row/_open.scss diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row/table_cell.test.tsx b/src/plugins/discover/public/components/doc_table/components/table_row/table_cell.test.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row/table_cell.test.tsx rename to src/plugins/discover/public/components/doc_table/components/table_row/table_cell.test.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row/table_cell.tsx b/src/plugins/discover/public/components/doc_table/components/table_row/table_cell.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row/table_cell.tsx rename to src/plugins/discover/public/components/doc_table/components/table_row/table_cell.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row/table_cell_actions.tsx b/src/plugins/discover/public/components/doc_table/components/table_row/table_cell_actions.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row/table_cell_actions.tsx rename to src/plugins/discover/public/components/doc_table/components/table_row/table_cell_actions.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row_details.tsx b/src/plugins/discover/public/components/doc_table/components/table_row_details.tsx similarity index 99% rename from src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row_details.tsx rename to src/plugins/discover/public/components/doc_table/components/table_row_details.tsx index c3ff53fe2d3a8..02d0ee4f2272a 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row_details.tsx +++ b/src/plugins/discover/public/components/doc_table/components/table_row_details.tsx @@ -9,7 +9,6 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink, EuiTitle } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; - interface TableRowDetailsProps { open: boolean; colLength: number; diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/create_doc_table_embeddable.tsx b/src/plugins/discover/public/components/doc_table/create_doc_table_embeddable.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/create_doc_table_embeddable.tsx rename to src/plugins/discover/public/components/doc_table/create_doc_table_embeddable.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_context.tsx b/src/plugins/discover/public/components/doc_table/doc_table_context.tsx similarity index 92% rename from src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_context.tsx rename to src/plugins/discover/public/components/doc_table/doc_table_context.tsx index 8d29efec73716..976d4e3d5bdf1 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_context.tsx +++ b/src/plugins/discover/public/components/doc_table/doc_table_context.tsx @@ -8,7 +8,7 @@ import React, { Fragment } from 'react'; import './index.scss'; -import { SkipBottomButton } from '../skip_bottom_button'; +import { SkipBottomButton } from '../../application/main/components/skip_bottom_button'; import { DocTableProps, DocTableRenderProps, DocTableWrapper } from './doc_table_wrapper'; const DocTableWrapperMemoized = React.memo(DocTableWrapper); diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_embeddable.tsx b/src/plugins/discover/public/components/doc_table/doc_table_embeddable.tsx similarity index 95% rename from src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_embeddable.tsx rename to src/plugins/discover/public/components/doc_table/doc_table_embeddable.tsx index 84edf147dea4c..0743c5ef813e8 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_embeddable.tsx +++ b/src/plugins/discover/public/components/doc_table/doc_table_embeddable.tsx @@ -10,12 +10,12 @@ import React, { memo, useCallback, useEffect, useMemo, useRef } from 'react'; import './index.scss'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; -import { SAMPLE_SIZE_SETTING } from '../../../../../../common'; +import { SAMPLE_SIZE_SETTING } from '../../../common'; import { usePager } from './lib/use_pager'; import { ToolBarPagination } from './components/pager/tool_bar_pagination'; import { DocTableProps, DocTableRenderProps, DocTableWrapper } from './doc_table_wrapper'; -import { TotalDocuments } from '../total_documents/total_documents'; -import { getServices } from '../../../../../kibana_services'; +import { TotalDocuments } from '../../application/main/components/total_documents/total_documents'; +import { getServices } from '../../kibana_services'; export interface DocTableEmbeddableProps extends DocTableProps { totalHitCount: number; diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_infinite.tsx b/src/plugins/discover/public/components/doc_table/doc_table_infinite.tsx similarity index 98% rename from src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_infinite.tsx rename to src/plugins/discover/public/components/doc_table/doc_table_infinite.tsx index dddfefa906962..d2e93cdae452e 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_infinite.tsx +++ b/src/plugins/discover/public/components/doc_table/doc_table_infinite.tsx @@ -12,7 +12,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { debounce } from 'lodash'; import { EuiButtonEmpty } from '@elastic/eui'; import { DocTableProps, DocTableRenderProps, DocTableWrapper } from './doc_table_wrapper'; -import { SkipBottomButton } from '../skip_bottom_button'; +import { SkipBottomButton } from '../../application/main/components/skip_bottom_button'; import { shouldLoadNextDocPatch } from './lib/should_load_next_doc_patch'; const FOOTER_PADDING = { padding: 0 }; diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.test.tsx b/src/plugins/discover/public/components/doc_table/doc_table_wrapper.test.tsx similarity index 92% rename from src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.test.tsx rename to src/plugins/discover/public/components/doc_table/doc_table_wrapper.test.tsx index df5869bd61e52..a17a5c9b87d73 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.test.tsx +++ b/src/plugins/discover/public/components/doc_table/doc_table_wrapper.test.tsx @@ -8,11 +8,11 @@ import React from 'react'; import { findTestSubject, mountWithIntl } from '@kbn/test/jest'; -import { setServices } from '../../../../../kibana_services'; -import { indexPatternMock } from '../../../../../__mocks__/index_pattern'; +import { setServices } from '../../kibana_services'; +import { indexPatternMock } from '../../__mocks__/index_pattern'; import { DocTableWrapper, DocTableWrapperProps } from './doc_table_wrapper'; import { DocTableRow } from './components/table_row'; -import { discoverServiceMock } from '../../../../../__mocks__/services'; +import { discoverServiceMock } from '../../__mocks__/services'; const mountComponent = (props: DocTableWrapperProps) => { return mountWithIntl(); diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx b/src/plugins/discover/public/components/doc_table/doc_table_wrapper.tsx similarity index 95% rename from src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx rename to src/plugins/discover/public/components/doc_table/doc_table_wrapper.tsx index 2fac1c828796d..139b835e2e5c4 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx +++ b/src/plugins/discover/public/components/doc_table/doc_table_wrapper.tsx @@ -11,18 +11,18 @@ import { EuiIcon, EuiSpacer, EuiText } from '@elastic/eui'; import type { IndexPattern, IndexPatternField } from 'src/plugins/data/common'; import { FormattedMessage } from '@kbn/i18n/react'; import { TableHeader } from './components/table_header/table_header'; -import { FORMATS_UI_SETTINGS } from '../../../../../../../field_formats/common'; +import { FORMATS_UI_SETTINGS } from '../../../../field_formats/common'; import { DOC_HIDE_TIME_COLUMN_SETTING, SAMPLE_SIZE_SETTING, SHOW_MULTIFIELDS, SORT_DEFAULT_ORDER_SETTING, -} from '../../../../../../common'; -import { getServices } from '../../../../../kibana_services'; +} from '../../../common'; +import { getServices } from '../../kibana_services'; import { SortOrder } from './components/table_header/helpers'; import { DocTableRow, TableRow } from './components/table_row'; -import { DocViewFilterFn } from '../../../../doc_views/doc_views_types'; -import { getFieldsToShow } from '../../../../helpers/get_fields_to_show'; +import { DocViewFilterFn } from '../../services/doc_views/doc_views_types'; +import { getFieldsToShow } from '../../utils/get_fields_to_show'; export interface DocTableProps { /** diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/index.scss b/src/plugins/discover/public/components/doc_table/index.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/index.scss rename to src/plugins/discover/public/components/doc_table/index.scss diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/index.ts b/src/plugins/discover/public/components/doc_table/index.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/index.ts rename to src/plugins/discover/public/components/doc_table/index.ts diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/get_default_sort.test.ts b/src/plugins/discover/public/components/doc_table/lib/get_default_sort.test.ts similarity index 95% rename from src/plugins/discover/public/application/apps/main/components/doc_table/lib/get_default_sort.test.ts rename to src/plugins/discover/public/components/doc_table/lib/get_default_sort.test.ts index 3a62108a16bef..68e7b43eceb9e 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/get_default_sort.test.ts +++ b/src/plugins/discover/public/components/doc_table/lib/get_default_sort.test.ts @@ -10,7 +10,7 @@ import { getDefaultSort } from './get_default_sort'; import { stubIndexPattern, stubIndexPatternWithoutTimeField, -} from '../../../../../../../../data/common/stubs'; +} from '../../../../../data/common/stubs'; describe('getDefaultSort function', function () { test('should be a function', function () { diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/get_default_sort.ts b/src/plugins/discover/public/components/doc_table/lib/get_default_sort.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/lib/get_default_sort.ts rename to src/plugins/discover/public/components/doc_table/lib/get_default_sort.ts diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/get_sort.test.ts b/src/plugins/discover/public/components/doc_table/lib/get_sort.test.ts similarity index 98% rename from src/plugins/discover/public/application/apps/main/components/doc_table/lib/get_sort.test.ts rename to src/plugins/discover/public/components/doc_table/lib/get_sort.test.ts index 9f7204805dc6f..7deb8075ac286 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/get_sort.test.ts +++ b/src/plugins/discover/public/components/doc_table/lib/get_sort.test.ts @@ -10,7 +10,7 @@ import { getSort, getSortArray } from './get_sort'; import { stubIndexPattern, stubIndexPatternWithoutTimeField, -} from '../../../../../../../../data/common/stubs'; +} from '../../../../../data/common/stubs'; describe('docTable', function () { describe('getSort function', function () { diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/get_sort.ts b/src/plugins/discover/public/components/doc_table/lib/get_sort.ts similarity index 97% rename from src/plugins/discover/public/application/apps/main/components/doc_table/lib/get_sort.ts rename to src/plugins/discover/public/components/doc_table/lib/get_sort.ts index 1e597f85666fc..bdbb3703ff87d 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/get_sort.ts +++ b/src/plugins/discover/public/components/doc_table/lib/get_sort.ts @@ -7,7 +7,7 @@ */ import { isPlainObject } from 'lodash'; -import { IndexPattern } from '../../../../../../../../data/public'; +import { IndexPattern } from '../../../../../data/public'; export type SortPairObj = Record; export type SortPairArr = [string, string]; diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/get_sort_for_search_source.test.ts b/src/plugins/discover/public/components/doc_table/lib/get_sort_for_search_source.test.ts similarity index 97% rename from src/plugins/discover/public/application/apps/main/components/doc_table/lib/get_sort_for_search_source.test.ts rename to src/plugins/discover/public/components/doc_table/lib/get_sort_for_search_source.test.ts index 061a458037100..de032c3748fcb 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/get_sort_for_search_source.test.ts +++ b/src/plugins/discover/public/components/doc_table/lib/get_sort_for_search_source.test.ts @@ -11,7 +11,7 @@ import { SortOrder } from '../components/table_header/helpers'; import { stubIndexPattern, stubIndexPatternWithoutTimeField, -} from '../../../../../../../../data/common/stubs'; +} from '../../../../../data/common/stubs'; describe('getSortForSearchSource function', function () { test('should be a function', function () { diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/get_sort_for_search_source.ts b/src/plugins/discover/public/components/doc_table/lib/get_sort_for_search_source.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/lib/get_sort_for_search_source.ts rename to src/plugins/discover/public/components/doc_table/lib/get_sort_for_search_source.ts diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.scss b/src/plugins/discover/public/components/doc_table/lib/row_formatter.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.scss rename to src/plugins/discover/public/components/doc_table/lib/row_formatter.scss diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.test.ts b/src/plugins/discover/public/components/doc_table/lib/row_formatter.test.ts similarity index 95% rename from src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.test.ts rename to src/plugins/discover/public/components/doc_table/lib/row_formatter.test.ts index 2e777a18ce906..ada9c1682a35b 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.test.ts +++ b/src/plugins/discover/public/components/doc_table/lib/row_formatter.test.ts @@ -8,11 +8,11 @@ import ReactDOM from 'react-dom/server'; import { formatRow, formatTopLevelObject } from './row_formatter'; -import { IndexPattern } from '../../../../../../../../data/common'; -import { fieldFormatsMock } from '../../../../../../../../field_formats/common/mocks'; -import { setServices } from '../../../../../../kibana_services'; -import { DiscoverServices } from '../../../../../../build_services'; -import { stubbedSavedObjectIndexPattern } from '../../../../../../../../data/common/stubs'; +import { IndexPattern } from '../../../../../data/common'; +import { fieldFormatsMock } from '../../../../../field_formats/common/mocks'; +import { setServices } from '../../../kibana_services'; +import { DiscoverServices } from '../../../build_services'; +import { stubbedSavedObjectIndexPattern } from '../../../../../data/common/stubs'; describe('Row formatter', () => { const hit = { diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.tsx b/src/plugins/discover/public/components/doc_table/lib/row_formatter.tsx similarity index 93% rename from src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.tsx rename to src/plugins/discover/public/components/doc_table/lib/row_formatter.tsx index d5660a091f0aa..0ec611a307513 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.tsx +++ b/src/plugins/discover/public/components/doc_table/lib/row_formatter.tsx @@ -9,9 +9,9 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import React, { Fragment } from 'react'; import type { IndexPattern } from 'src/plugins/data/common'; -import { MAX_DOC_FIELDS_DISPLAYED } from '../../../../../../../common'; -import { getServices } from '../../../../../../kibana_services'; -import { formatHit } from '../../../../../helpers/format_hit'; +import { MAX_DOC_FIELDS_DISPLAYED } from '../../../../common'; +import { getServices } from '../../../kibana_services'; +import { formatHit } from '../../../utils/format_hit'; import './row_formatter.scss'; diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/should_load_next_doc_patch.test.ts b/src/plugins/discover/public/components/doc_table/lib/should_load_next_doc_patch.test.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/lib/should_load_next_doc_patch.test.ts rename to src/plugins/discover/public/components/doc_table/lib/should_load_next_doc_patch.test.ts diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/should_load_next_doc_patch.ts b/src/plugins/discover/public/components/doc_table/lib/should_load_next_doc_patch.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/lib/should_load_next_doc_patch.ts rename to src/plugins/discover/public/components/doc_table/lib/should_load_next_doc_patch.ts diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/use_pager.test.tsx b/src/plugins/discover/public/components/doc_table/lib/use_pager.test.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/lib/use_pager.test.tsx rename to src/plugins/discover/public/components/doc_table/lib/use_pager.test.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/use_pager.ts b/src/plugins/discover/public/components/doc_table/lib/use_pager.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/lib/use_pager.ts rename to src/plugins/discover/public/components/doc_table/lib/use_pager.ts diff --git a/src/plugins/discover/public/application/components/field_name/__snapshots__/field_name.test.tsx.snap b/src/plugins/discover/public/components/field_name/__snapshots__/field_name.test.tsx.snap similarity index 100% rename from src/plugins/discover/public/application/components/field_name/__snapshots__/field_name.test.tsx.snap rename to src/plugins/discover/public/components/field_name/__snapshots__/field_name.test.tsx.snap diff --git a/src/plugins/discover/public/application/components/field_name/field_name.scss b/src/plugins/discover/public/components/field_name/field_name.scss similarity index 100% rename from src/plugins/discover/public/application/components/field_name/field_name.scss rename to src/plugins/discover/public/components/field_name/field_name.scss diff --git a/src/plugins/discover/public/application/components/field_name/field_name.test.tsx b/src/plugins/discover/public/components/field_name/field_name.test.tsx similarity index 100% rename from src/plugins/discover/public/application/components/field_name/field_name.test.tsx rename to src/plugins/discover/public/components/field_name/field_name.test.tsx diff --git a/src/plugins/discover/public/application/components/field_name/field_name.tsx b/src/plugins/discover/public/components/field_name/field_name.tsx similarity index 92% rename from src/plugins/discover/public/application/components/field_name/field_name.tsx rename to src/plugins/discover/public/components/field_name/field_name.tsx index 0e8ca31f6379a..b7a87875c64e3 100644 --- a/src/plugins/discover/public/application/components/field_name/field_name.tsx +++ b/src/plugins/discover/public/components/field_name/field_name.tsx @@ -11,10 +11,10 @@ import './field_name.scss'; import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { FieldIcon, FieldIconProps } from '../../../../../kibana_react/public'; +import { FieldIcon, FieldIconProps } from '../../../../kibana_react/public'; import { getFieldTypeName } from './field_type_name'; -import { IndexPatternField } from '../../../../../data/public'; -import { getFieldSubtypeMulti } from '../../../../../data/common'; +import { IndexPatternField } from '../../../../data/public'; +import { getFieldSubtypeMulti } from '../../../../data/common'; interface Props { fieldName: string; diff --git a/src/plugins/discover/public/application/components/field_name/field_type_name.ts b/src/plugins/discover/public/components/field_name/field_type_name.ts similarity index 100% rename from src/plugins/discover/public/application/components/field_name/field_type_name.ts rename to src/plugins/discover/public/components/field_name/field_type_name.ts diff --git a/src/plugins/discover/public/application/components/help_menu/help_menu_util.ts b/src/plugins/discover/public/components/help_menu/help_menu_util.ts similarity index 100% rename from src/plugins/discover/public/application/components/help_menu/help_menu_util.ts rename to src/plugins/discover/public/components/help_menu/help_menu_util.ts diff --git a/src/plugins/discover/public/components/index.ts b/src/plugins/discover/public/components/index.ts new file mode 100644 index 0000000000000..a794b8c90a477 --- /dev/null +++ b/src/plugins/discover/public/components/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 + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { DeferredSpinner } from './common/deferred_spinner'; diff --git a/src/plugins/discover/public/application/components/json_code_editor/__snapshots__/json_code_editor.test.tsx.snap b/src/plugins/discover/public/components/json_code_editor/__snapshots__/json_code_editor.test.tsx.snap similarity index 100% rename from src/plugins/discover/public/application/components/json_code_editor/__snapshots__/json_code_editor.test.tsx.snap rename to src/plugins/discover/public/components/json_code_editor/__snapshots__/json_code_editor.test.tsx.snap diff --git a/src/plugins/discover/public/application/components/json_code_editor/json_code_editor.scss b/src/plugins/discover/public/components/json_code_editor/json_code_editor.scss similarity index 100% rename from src/plugins/discover/public/application/components/json_code_editor/json_code_editor.scss rename to src/plugins/discover/public/components/json_code_editor/json_code_editor.scss diff --git a/src/plugins/discover/public/application/components/json_code_editor/json_code_editor.test.tsx b/src/plugins/discover/public/components/json_code_editor/json_code_editor.test.tsx similarity index 100% rename from src/plugins/discover/public/application/components/json_code_editor/json_code_editor.test.tsx rename to src/plugins/discover/public/components/json_code_editor/json_code_editor.test.tsx diff --git a/src/plugins/discover/public/application/components/json_code_editor/json_code_editor.tsx b/src/plugins/discover/public/components/json_code_editor/json_code_editor.tsx similarity index 100% rename from src/plugins/discover/public/application/components/json_code_editor/json_code_editor.tsx rename to src/plugins/discover/public/components/json_code_editor/json_code_editor.tsx diff --git a/src/plugins/discover/public/application/components/json_code_editor/json_code_editor_common.tsx b/src/plugins/discover/public/components/json_code_editor/json_code_editor_common.tsx similarity index 97% rename from src/plugins/discover/public/application/components/json_code_editor/json_code_editor_common.tsx rename to src/plugins/discover/public/components/json_code_editor/json_code_editor_common.tsx index cab4eae41afb8..07d3ec2e759a3 100644 --- a/src/plugins/discover/public/application/components/json_code_editor/json_code_editor_common.tsx +++ b/src/plugins/discover/public/components/json_code_editor/json_code_editor_common.tsx @@ -12,7 +12,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { monaco, XJsonLang } from '@kbn/monaco'; import { EuiButtonEmpty, EuiCopy, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; -import { CodeEditor } from '../../../../../kibana_react/public'; +import { CodeEditor } from '../../../../kibana_react/public'; const codeEditorAriaLabel = i18n.translate('discover.json.codeEditorAriaLabel', { defaultMessage: 'Read only JSON view of an elasticsearch document', diff --git a/src/plugins/discover/public/application/apps/main/components/view_mode_toggle/_index.scss b/src/plugins/discover/public/components/view_mode_toggle/_index.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/view_mode_toggle/_index.scss rename to src/plugins/discover/public/components/view_mode_toggle/_index.scss diff --git a/src/plugins/discover/public/application/apps/main/components/view_mode_toggle/_view_mode_toggle.scss b/src/plugins/discover/public/components/view_mode_toggle/_view_mode_toggle.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/view_mode_toggle/_view_mode_toggle.scss rename to src/plugins/discover/public/components/view_mode_toggle/_view_mode_toggle.scss diff --git a/src/plugins/discover/public/application/apps/main/components/view_mode_toggle/constants.ts b/src/plugins/discover/public/components/view_mode_toggle/constants.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/view_mode_toggle/constants.ts rename to src/plugins/discover/public/components/view_mode_toggle/constants.ts diff --git a/src/plugins/discover/public/application/apps/main/components/view_mode_toggle/index.ts b/src/plugins/discover/public/components/view_mode_toggle/index.ts similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/view_mode_toggle/index.ts rename to src/plugins/discover/public/components/view_mode_toggle/index.ts diff --git a/src/plugins/discover/public/application/apps/main/components/view_mode_toggle/view_mode_toggle.tsx b/src/plugins/discover/public/components/view_mode_toggle/view_mode_toggle.tsx similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/view_mode_toggle/view_mode_toggle.tsx rename to src/plugins/discover/public/components/view_mode_toggle/view_mode_toggle.tsx diff --git a/src/plugins/discover/public/application/embeddable/constants.ts b/src/plugins/discover/public/embeddable/constants.ts similarity index 84% rename from src/plugins/discover/public/application/embeddable/constants.ts rename to src/plugins/discover/public/embeddable/constants.ts index 57ff91049cd0d..6c9de47a0f710 100644 --- a/src/plugins/discover/public/application/embeddable/constants.ts +++ b/src/plugins/discover/public/embeddable/constants.ts @@ -6,4 +6,4 @@ * Side Public License, v 1. */ -export { SEARCH_EMBEDDABLE_TYPE } from '../../../common/index'; +export { SEARCH_EMBEDDABLE_TYPE } from '../../common'; diff --git a/src/plugins/discover/public/application/embeddable/index.ts b/src/plugins/discover/public/embeddable/index.ts similarity index 100% rename from src/plugins/discover/public/application/embeddable/index.ts rename to src/plugins/discover/public/embeddable/index.ts diff --git a/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx b/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx similarity index 92% rename from src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx rename to src/plugins/discover/public/embeddable/saved_search_embeddable.tsx index 808962dc8319d..914b9f25d29ae 100644 --- a/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx +++ b/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx @@ -11,13 +11,13 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { i18n } from '@kbn/i18n'; import { isEqual } from 'lodash'; -import { Container, Embeddable } from '../../../../embeddable/public'; +import { Container, Embeddable } from '../../../embeddable/public'; import { ISearchEmbeddable, SearchInput, SearchOutput } from './types'; -import { SavedSearch } from '../../saved_searches'; -import { Adapters, RequestAdapter } from '../../../../inspector/common'; +import { SavedSearch } from '../services/saved_searches'; +import { Adapters, RequestAdapter } from '../../../inspector/common'; import { SEARCH_EMBEDDABLE_TYPE } from './constants'; -import { APPLY_FILTER_TRIGGER, esFilters, FilterManager } from '../../../../data/public'; -import { DiscoverServices } from '../../build_services'; +import { APPLY_FILTER_TRIGGER, esFilters, FilterManager } from '../../../data/public'; +import { DiscoverServices } from '../build_services'; import { Filter, IndexPattern, @@ -25,11 +25,11 @@ import { ISearchSource, Query, TimeRange, -} from '../../../../data/common'; -import { ElasticSearchHit } from '../doc_views/doc_views_types'; +} from '../../../data/common'; +import { ElasticSearchHit } from '../services/doc_views/doc_views_types'; import { SavedSearchEmbeddableComponent } from './saved_search_embeddable_component'; -import { UiActionsStart } from '../../../../ui_actions/public'; -import { getServices } from '../../kibana_services'; +import { UiActionsStart } from '../../../ui_actions/public'; +import { getServices } from '../kibana_services'; import { DOC_HIDE_TIME_COLUMN_SETTING, DOC_TABLE_LEGACY, @@ -37,16 +37,16 @@ import { SEARCH_FIELDS_FROM_SOURCE, SHOW_FIELD_STATISTICS, SORT_DEFAULT_ORDER_SETTING, -} from '../../../common'; -import * as columnActions from '../apps/main/components/doc_table/actions/columns'; -import { handleSourceColumnState } from '../helpers/state_helpers'; +} from '../../common'; +import * as columnActions from '../components/doc_table/actions/columns'; +import { handleSourceColumnState } from '../utils/state_helpers'; import { DiscoverGridProps } from '../components/discover_grid/discover_grid'; import { DiscoverGridSettings } from '../components/discover_grid/types'; -import { DocTableProps } from '../apps/main/components/doc_table/doc_table_wrapper'; -import { getDefaultSort } from '../apps/main/components/doc_table'; -import { SortOrder } from '../apps/main/components/doc_table/components/table_header/helpers'; -import { updateSearchSource } from './helpers/update_search_source'; -import { VIEW_MODE } from '../apps/main/components/view_mode_toggle'; +import { DocTableProps } from '../components/doc_table/doc_table_wrapper'; +import { getDefaultSort } from '../components/doc_table'; +import { SortOrder } from '../components/doc_table/components/table_header/helpers'; +import { updateSearchSource } from './utils/update_search_source'; +import { VIEW_MODE } from '../components/view_mode_toggle'; import { FieldStatsTableEmbeddable } from '../components/data_visualizer_grid/field_stats_table_embeddable'; export type SearchProps = Partial & diff --git a/src/plugins/discover/public/application/embeddable/saved_search_embeddable_component.tsx b/src/plugins/discover/public/embeddable/saved_search_embeddable_component.tsx similarity index 86% rename from src/plugins/discover/public/application/embeddable/saved_search_embeddable_component.tsx rename to src/plugins/discover/public/embeddable/saved_search_embeddable_component.tsx index 058794fa59a18..5d7907d3cf791 100644 --- a/src/plugins/discover/public/application/embeddable/saved_search_embeddable_component.tsx +++ b/src/plugins/discover/public/embeddable/saved_search_embeddable_component.tsx @@ -9,8 +9,8 @@ import React from 'react'; import { DiscoverGridEmbeddable, DiscoverGridEmbeddableProps } from './saved_search_grid'; -import { DiscoverDocTableEmbeddable } from '../apps/main/components/doc_table/create_doc_table_embeddable'; -import { DocTableEmbeddableProps } from '../apps/main/components/doc_table/doc_table_embeddable'; +import { DiscoverDocTableEmbeddable } from '../components/doc_table/create_doc_table_embeddable'; +import { DocTableEmbeddableProps } from '../components/doc_table/doc_table_embeddable'; import { SearchProps } from './saved_search_embeddable'; interface SavedSearchEmbeddableComponentProps { diff --git a/src/plugins/discover/public/application/embeddable/saved_search_grid.tsx b/src/plugins/discover/public/embeddable/saved_search_grid.tsx similarity index 88% rename from src/plugins/discover/public/application/embeddable/saved_search_grid.tsx rename to src/plugins/discover/public/embeddable/saved_search_grid.tsx index 0dce6d2b3abe8..e4d4bf64a74f1 100644 --- a/src/plugins/discover/public/application/embeddable/saved_search_grid.tsx +++ b/src/plugins/discover/public/embeddable/saved_search_grid.tsx @@ -9,9 +9,9 @@ import React, { useState } from 'react'; import { I18nProvider } from '@kbn/i18n/react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { DiscoverGrid, DiscoverGridProps } from '../components/discover_grid/discover_grid'; -import { getServices } from '../../kibana_services'; -import { ElasticSearchHit } from '../doc_views/doc_views_types'; -import { TotalDocuments } from '../apps/main/components/total_documents/total_documents'; +import { getServices } from '../kibana_services'; +import { ElasticSearchHit } from '../services/doc_views/doc_views_types'; +import { TotalDocuments } from '../application/main/components/total_documents/total_documents'; export interface DiscoverGridEmbeddableProps extends DiscoverGridProps { totalHitCount: number; diff --git a/src/plugins/discover/public/application/embeddable/search_embeddable.scss b/src/plugins/discover/public/embeddable/search_embeddable.scss similarity index 100% rename from src/plugins/discover/public/application/embeddable/search_embeddable.scss rename to src/plugins/discover/public/embeddable/search_embeddable.scss diff --git a/src/plugins/discover/public/application/embeddable/search_embeddable_factory.ts b/src/plugins/discover/public/embeddable/search_embeddable_factory.ts similarity index 94% rename from src/plugins/discover/public/application/embeddable/search_embeddable_factory.ts rename to src/plugins/discover/public/embeddable/search_embeddable_factory.ts index a8b492d368768..8fbedf3979663 100644 --- a/src/plugins/discover/public/application/embeddable/search_embeddable_factory.ts +++ b/src/plugins/discover/public/embeddable/search_embeddable_factory.ts @@ -8,14 +8,14 @@ import { i18n } from '@kbn/i18n'; import { UiActionsStart } from 'src/plugins/ui_actions/public'; -import { getServices } from '../../kibana_services'; +import { getServices } from '../kibana_services'; import { EmbeddableFactoryDefinition, Container, ErrorEmbeddable, -} from '../../../../embeddable/public'; +} from '../../../embeddable/public'; -import { TimeRange } from '../../../../data/public'; +import { TimeRange } from '../../../data/public'; import { SearchInput, SearchOutput } from './types'; import { SEARCH_EMBEDDABLE_TYPE } from './constants'; @@ -24,7 +24,7 @@ import { getSavedSearch, getSavedSearchUrl, throwErrorOnSavedSearchUrlConflict, -} from '../../saved_searches'; +} from '../services/saved_searches'; interface StartServices { executeTriggerActions: UiActionsStart['executeTriggerActions']; diff --git a/src/plugins/discover/public/application/embeddable/types.ts b/src/plugins/discover/public/embeddable/types.ts similarity index 86% rename from src/plugins/discover/public/application/embeddable/types.ts rename to src/plugins/discover/public/embeddable/types.ts index de109e3fa7879..bf9cc6e4954fe 100644 --- a/src/plugins/discover/public/application/embeddable/types.ts +++ b/src/plugins/discover/public/embeddable/types.ts @@ -12,9 +12,9 @@ import { EmbeddableOutput, IEmbeddable, } from 'src/plugins/embeddable/public'; -import { Filter, IndexPattern, TimeRange, Query } from '../../../../data/public'; -import { SavedSearch } from '../../saved_searches'; -import { SortOrder } from '../apps/main/components/doc_table/components/table_header/helpers'; +import { Filter, IndexPattern, TimeRange, Query } from '../../../data/public'; +import { SavedSearch } from '../services/saved_searches'; +import { SortOrder } from '../components/doc_table/components/table_header/helpers'; export interface SearchInput extends EmbeddableInput { timeRange: TimeRange; diff --git a/src/plugins/discover/public/application/embeddable/helpers/update_search_source.test.ts b/src/plugins/discover/public/embeddable/utils/update_search_source.test.ts similarity index 85% rename from src/plugins/discover/public/application/embeddable/helpers/update_search_source.test.ts rename to src/plugins/discover/public/embeddable/utils/update_search_source.test.ts index f09131cb5c926..cd2f6cf88cfa3 100644 --- a/src/plugins/discover/public/application/embeddable/helpers/update_search_source.test.ts +++ b/src/plugins/discover/public/embeddable/utils/update_search_source.test.ts @@ -5,10 +5,10 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { createSearchSourceMock } from '../../../../../data/common/search/search_source/mocks'; +import { createSearchSourceMock } from '../../../../data/common/search/search_source/mocks'; import { updateSearchSource } from './update_search_source'; -import { indexPatternMock } from '../../../__mocks__/index_pattern'; -import type { SortOrder } from '../../../saved_searches'; +import { indexPatternMock } from '../../__mocks__/index_pattern'; +import type { SortOrder } from '../../services/saved_searches'; describe('updateSearchSource', () => { const defaults = { diff --git a/src/plugins/discover/public/application/embeddable/helpers/update_search_source.ts b/src/plugins/discover/public/embeddable/utils/update_search_source.ts similarity index 81% rename from src/plugins/discover/public/application/embeddable/helpers/update_search_source.ts rename to src/plugins/discover/public/embeddable/utils/update_search_source.ts index 1d6c29d65ca85..7e24f96d503e8 100644 --- a/src/plugins/discover/public/application/embeddable/helpers/update_search_source.ts +++ b/src/plugins/discover/public/embeddable/utils/update_search_source.ts @@ -6,9 +6,9 @@ * Side Public License, v 1. */ -import { IndexPattern, ISearchSource } from '../../../../../data/common'; -import { getSortForSearchSource } from '../../apps/main/components/doc_table'; -import { SortPairArr } from '../../apps/main/components/doc_table/lib/get_sort'; +import { IndexPattern, ISearchSource } from '../../../../data/common'; +import { getSortForSearchSource } from '../../components/doc_table'; +import { SortPairArr } from '../../components/doc_table/lib/get_sort'; export const updateSearchSource = ( searchSource: ISearchSource, diff --git a/src/plugins/discover/public/application/embeddable/view_saved_search_action.test.ts b/src/plugins/discover/public/embeddable/view_saved_search_action.test.ts similarity index 89% rename from src/plugins/discover/public/application/embeddable/view_saved_search_action.test.ts rename to src/plugins/discover/public/embeddable/view_saved_search_action.test.ts index 990be8927766a..f0dbc0d1d7a57 100644 --- a/src/plugins/discover/public/application/embeddable/view_saved_search_action.test.ts +++ b/src/plugins/discover/public/embeddable/view_saved_search_action.test.ts @@ -10,15 +10,15 @@ import { ContactCardEmbeddable } from 'src/plugins/embeddable/public/lib/test_sa import { ViewSavedSearchAction } from './view_saved_search_action'; import { SavedSearchEmbeddable } from './saved_search_embeddable'; -import { createStartContractMock } from '../../__mocks__/start_contract'; -import { uiSettingsServiceMock } from '../../../../../core/public/mocks'; -import { savedSearchMock } from '../../__mocks__/saved_search'; -import { discoverServiceMock } from '../../__mocks__/services'; +import { createStartContractMock } from '../__mocks__/start_contract'; +import { uiSettingsServiceMock } from '../../../../core/public/mocks'; +import { savedSearchMock } from '../__mocks__/saved_search'; +import { discoverServiceMock } from '../__mocks__/services'; import { IndexPattern } from 'src/plugins/data/common'; import { createFilterManagerMock } from 'src/plugins/data/public/query/filter_manager/filter_manager.mock'; import { ViewMode } from 'src/plugins/embeddable/public'; -import { setServices } from '../../kibana_services'; -import type { DiscoverServices } from '../../build_services'; +import { setServices } from '../kibana_services'; +import type { DiscoverServices } from '../build_services'; const applicationMock = createStartContractMock(); const savedSearch = savedSearchMock; diff --git a/src/plugins/discover/public/application/embeddable/view_saved_search_action.ts b/src/plugins/discover/public/embeddable/view_saved_search_action.ts similarity index 89% rename from src/plugins/discover/public/application/embeddable/view_saved_search_action.ts rename to src/plugins/discover/public/embeddable/view_saved_search_action.ts index e4b97d011ff64..b9bbc21cfef2c 100644 --- a/src/plugins/discover/public/application/embeddable/view_saved_search_action.ts +++ b/src/plugins/discover/public/embeddable/view_saved_search_action.ts @@ -8,11 +8,11 @@ import { ActionExecutionContext } from 'src/plugins/ui_actions/public'; import { ApplicationStart } from 'kibana/public'; import { i18n } from '@kbn/i18n'; -import { IEmbeddable, ViewMode } from '../../../../embeddable/public'; -import { Action } from '../../../../ui_actions/public'; +import { IEmbeddable, ViewMode } from '../../../embeddable/public'; +import { Action } from '../../../ui_actions/public'; import { SavedSearchEmbeddable } from './saved_search_embeddable'; -import { SEARCH_EMBEDDABLE_TYPE } from '../../../common'; -import { getSavedSearchUrl } from '../../saved_searches'; +import { SEARCH_EMBEDDABLE_TYPE } from '../../common'; +import { getSavedSearchUrl } from '../services/saved_searches'; export const ACTION_VIEW_SAVED_SEARCH = 'ACTION_VIEW_SAVED_SEARCH'; diff --git a/src/plugins/discover/public/index.ts b/src/plugins/discover/public/index.ts index cb7b29afe3f9a..e7abbdfc328ab 100644 --- a/src/plugins/discover/public/index.ts +++ b/src/plugins/discover/public/index.ts @@ -9,23 +9,23 @@ import { PluginInitializerContext } from 'kibana/public'; import { DiscoverPlugin } from './plugin'; -export type { SavedSearch } from './saved_searches'; +export type { SavedSearch } from './services/saved_searches'; export { getSavedSearch, getSavedSearchFullPathUrl, getSavedSearchUrl, getSavedSearchUrlConflictMessage, throwErrorOnSavedSearchUrlConflict, -} from './saved_searches'; +} from './services/saved_searches'; export type { DiscoverSetup, DiscoverStart } from './plugin'; export function plugin(initializerContext: PluginInitializerContext) { return new DiscoverPlugin(initializerContext); } -export type { ISearchEmbeddable, SearchInput } from './application/embeddable'; -export { SEARCH_EMBEDDABLE_TYPE } from './application/embeddable'; -export { loadSharingDataHelpers } from './shared'; +export type { ISearchEmbeddable, SearchInput } from './embeddable'; +export { SEARCH_EMBEDDABLE_TYPE } from './embeddable'; +export { loadSharingDataHelpers } from './utils'; export type { DiscoverUrlGeneratorState } from './url_generator'; export { DISCOVER_APP_URL_GENERATOR } from './url_generator'; diff --git a/src/plugins/discover/public/kibana_services.ts b/src/plugins/discover/public/kibana_services.ts index c68d6fbf479a1..12b0a77a7865d 100644 --- a/src/plugins/discover/public/kibana_services.ts +++ b/src/plugins/discover/public/kibana_services.ts @@ -12,7 +12,7 @@ import type { ScopedHistory, AppMountParameters } from 'kibana/public'; import type { UiActionsStart } from 'src/plugins/ui_actions/public'; import { DiscoverServices } from './build_services'; import { createGetterSetter } from '../../kibana_utils/public'; -import { DocViewsRegistry } from './application/doc_views/doc_views_registry'; +import { DocViewsRegistry } from './services/doc_views/doc_views_registry'; let services: DiscoverServices | null = null; let uiActions: UiActionsStart; diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index 62a5a7972a278..766b2827c7cbd 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -33,8 +33,8 @@ import { SavedObjectsStart } from '../../saved_objects/public'; import { createKbnUrlTracker } from '../../kibana_utils/public'; import { DEFAULT_APP_CATEGORIES } from '../../../core/public'; import { UrlGeneratorState } from '../../share/public'; -import { DocViewInput, DocViewInputFn } from './application/doc_views/doc_views_types'; -import { DocViewsRegistry } from './application/doc_views/doc_views_registry'; +import { DocViewInput, DocViewInputFn } from './services/doc_views/doc_views_types'; +import { DocViewsRegistry } from './services/doc_views/doc_views_registry'; import { setDocViewsRegistry, setUrlTracker, @@ -54,15 +54,15 @@ import { SEARCH_SESSION_ID_QUERY_PARAM, } from './url_generator'; import { DiscoverAppLocatorDefinition, DiscoverAppLocator } from './locator'; -import { SearchEmbeddableFactory } from './application/embeddable'; +import { SearchEmbeddableFactory } from './embeddable'; import { UsageCollectionSetup } from '../../usage_collection/public'; import { replaceUrlHashQuery } from '../../kibana_utils/public/'; import { IndexPatternFieldEditorStart } from '../../../plugins/index_pattern_field_editor/public'; -import { DeferredSpinner } from './shared'; -import { ViewSavedSearchAction } from './application/embeddable/view_saved_search_action'; +import { DeferredSpinner } from './components'; +import { ViewSavedSearchAction } from './embeddable/view_saved_search_action'; import type { SpacesPluginStart } from '../../../../x-pack/plugins/spaces/public'; import { FieldFormatsStart } from '../../field_formats/public'; -import { injectTruncateStyles } from './application/helpers/truncate_styles'; +import { injectTruncateStyles } from './utils/truncate_styles'; import { TRUNCATE_MAX_HEIGHT } from '../common'; declare module '../../share/public' { @@ -71,11 +71,8 @@ declare module '../../share/public' { } } -const DocViewerTable = React.lazy(() => import('./application/components/table/table')); - -const SourceViewer = React.lazy( - () => import('./application/components/source_viewer/source_viewer') -); +const DocViewerTable = React.lazy(() => import('./services/doc_views/components/doc_viewer_table')); +const SourceViewer = React.lazy(() => import('./services/doc_views/components/doc_viewer_source')); /** * @public @@ -350,11 +347,9 @@ export class DiscoverPlugin await depsStart.data.indexPatterns.clearCache(); const { renderApp } = await import('./application'); - // FIXME: Temporarily hide overflow-y in Discover app when Field Stats table is shown // due to EUI bug https://github.com/elastic/eui/pull/5152 params.element.classList.add('dscAppWrapper'); - const unmount = renderApp(params.element); return () => { unlistenParentHistory(); diff --git a/src/plugins/discover/public/application/components/doc_viewer/__snapshots__/doc_viewer.test.tsx.snap b/src/plugins/discover/public/services/doc_views/components/doc_viewer/__snapshots__/doc_viewer.test.tsx.snap similarity index 100% rename from src/plugins/discover/public/application/components/doc_viewer/__snapshots__/doc_viewer.test.tsx.snap rename to src/plugins/discover/public/services/doc_views/components/doc_viewer/__snapshots__/doc_viewer.test.tsx.snap diff --git a/src/plugins/discover/public/application/components/doc_viewer/__snapshots__/doc_viewer_render_tab.test.tsx.snap b/src/plugins/discover/public/services/doc_views/components/doc_viewer/__snapshots__/doc_viewer_render_tab.test.tsx.snap similarity index 100% rename from src/plugins/discover/public/application/components/doc_viewer/__snapshots__/doc_viewer_render_tab.test.tsx.snap rename to src/plugins/discover/public/services/doc_views/components/doc_viewer/__snapshots__/doc_viewer_render_tab.test.tsx.snap diff --git a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer.scss b/src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer.scss similarity index 100% rename from src/plugins/discover/public/application/components/doc_viewer/doc_viewer.scss rename to src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer.scss diff --git a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer.test.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer.test.tsx similarity index 93% rename from src/plugins/discover/public/application/components/doc_viewer/doc_viewer.test.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer.test.tsx index de0353a020a67..bedf1047bc4ec 100644 --- a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer.test.tsx +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer.test.tsx @@ -10,10 +10,10 @@ import React from 'react'; import { mount, shallow } from 'enzyme'; import { DocViewer } from './doc_viewer'; import { findTestSubject } from '@elastic/eui/lib/test'; -import { getDocViewsRegistry } from '../../../kibana_services'; -import { DocViewRenderProps } from '../../doc_views/doc_views_types'; +import { getDocViewsRegistry } from '../../../../kibana_services'; +import { DocViewRenderProps } from '../../doc_views_types'; -jest.mock('../../../kibana_services', () => { +jest.mock('../../../../kibana_services', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any let registry: any[] = []; return { diff --git a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer.tsx similarity index 91% rename from src/plugins/discover/public/application/components/doc_viewer/doc_viewer.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer.tsx index d0476d4c38b48..9b627b1569275 100644 --- a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer.tsx +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer.tsx @@ -9,9 +9,9 @@ import './doc_viewer.scss'; import React from 'react'; import { EuiTabbedContent } from '@elastic/eui'; -import { getDocViewsRegistry } from '../../../kibana_services'; +import { getDocViewsRegistry } from '../../../../kibana_services'; import { DocViewerTab } from './doc_viewer_tab'; -import { DocView, DocViewRenderProps } from '../../doc_views/doc_views_types'; +import { DocView, DocViewRenderProps } from '../../doc_views_types'; /** * Rendering tabs with different views of 1 Elasticsearch hit in Discover. diff --git a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer_render_error.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer_render_error.tsx similarity index 100% rename from src/plugins/discover/public/application/components/doc_viewer/doc_viewer_render_error.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer_render_error.tsx diff --git a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer_render_tab.test.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer_render_tab.test.tsx similarity index 92% rename from src/plugins/discover/public/application/components/doc_viewer/doc_viewer_render_tab.test.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer_render_tab.test.tsx index de76074357f63..5c61938a9e830 100644 --- a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer_render_tab.test.tsx +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer_render_tab.test.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { mount } from 'enzyme'; import { DocViewRenderTab } from './doc_viewer_render_tab'; -import { DocViewRenderProps } from '../../doc_views/doc_views_types'; +import { DocViewRenderProps } from '../../doc_views_types'; test('Mounting and unmounting DocViewerRenderTab', () => { const unmountFn = jest.fn(); diff --git a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer_render_tab.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer_render_tab.tsx similarity index 97% rename from src/plugins/discover/public/application/components/doc_viewer/doc_viewer_render_tab.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer_render_tab.tsx index a6967cac8cdcc..257f40a9850a1 100644 --- a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer_render_tab.tsx +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer_render_tab.tsx @@ -7,7 +7,7 @@ */ import React, { useRef, useEffect } from 'react'; -import { DocViewRenderFn, DocViewRenderProps } from '../../doc_views/doc_views_types'; +import { DocViewRenderFn, DocViewRenderProps } from '../../doc_views_types'; interface Props { render: DocViewRenderFn; diff --git a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer_tab.test.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer_tab.test.tsx similarity index 90% rename from src/plugins/discover/public/application/components/doc_viewer/doc_viewer_tab.test.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer_tab.test.tsx index 188deba755445..3537699e4fe20 100644 --- a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer_tab.test.tsx +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer_tab.test.tsx @@ -9,8 +9,8 @@ import React from 'react'; import { shallow } from 'enzyme'; import { DocViewerTab } from './doc_viewer_tab'; -import { ElasticSearchHit } from '../../doc_views/doc_views_types'; -import { indexPatternMock } from '../../../__mocks__/index_pattern'; +import { ElasticSearchHit } from '../../doc_views_types'; +import { indexPatternMock } from '../../../../__mocks__/index_pattern'; describe('DocViewerTab', () => { test('changing columns triggers an update', () => { diff --git a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer_tab.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer_tab.tsx similarity index 94% rename from src/plugins/discover/public/application/components/doc_viewer/doc_viewer_tab.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer_tab.tsx index 75ec5a62e9299..f43e445737820 100644 --- a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer_tab.tsx +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer/doc_viewer_tab.tsx @@ -10,9 +10,9 @@ import React from 'react'; import { isEqual } from 'lodash'; import { DocViewRenderTab } from './doc_viewer_render_tab'; import { DocViewerError } from './doc_viewer_render_error'; -import { DocViewRenderFn, DocViewRenderProps } from '../../doc_views/doc_views_types'; -import { getServices } from '../../../kibana_services'; -import { KibanaContextProvider } from '../../../../../kibana_react/public'; +import { DocViewRenderFn, DocViewRenderProps } from '../../doc_views_types'; +import { getServices } from '../../../../kibana_services'; +import { KibanaContextProvider } from '../../../../../../kibana_react/public'; interface Props { id: number; diff --git a/src/plugins/discover/public/services/doc_views/components/doc_viewer/index.ts b/src/plugins/discover/public/services/doc_views/components/doc_viewer/index.ts new file mode 100644 index 0000000000000..3801c9b2de669 --- /dev/null +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer/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 + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +export { DocViewer } from './doc_viewer'; diff --git a/src/plugins/discover/public/application/components/source_viewer/__snapshots__/source_viewer.test.tsx.snap b/src/plugins/discover/public/services/doc_views/components/doc_viewer_source/__snapshots__/source.test.tsx.snap similarity index 99% rename from src/plugins/discover/public/application/components/source_viewer/__snapshots__/source_viewer.test.tsx.snap rename to src/plugins/discover/public/services/doc_views/components/doc_viewer_source/__snapshots__/source.test.tsx.snap index 761263ee861b9..352006ba1c83b 100644 --- a/src/plugins/discover/public/application/components/source_viewer/__snapshots__/source_viewer.test.tsx.snap +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer_source/__snapshots__/source.test.tsx.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Source Viewer component renders error state 1`] = ` -
- + `; exports[`Source Viewer component renders json code editor 1`] = ` - - + `; exports[`Source Viewer component renders loading state 1`] = ` - - + `; diff --git a/src/plugins/discover/public/services/doc_views/components/doc_viewer_source/index.ts b/src/plugins/discover/public/services/doc_views/components/doc_viewer_source/index.ts new file mode 100644 index 0000000000000..2611bb6f0c4b9 --- /dev/null +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer_source/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 + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import { DocViewerSource } from './source'; + +// Required for usage in React.lazy +// eslint-disable-next-line import/no-default-export +export default DocViewerSource; diff --git a/src/plugins/discover/public/application/components/source_viewer/source_viewer.scss b/src/plugins/discover/public/services/doc_views/components/doc_viewer_source/source.scss similarity index 100% rename from src/plugins/discover/public/application/components/source_viewer/source_viewer.scss rename to src/plugins/discover/public/services/doc_views/components/doc_viewer_source/source.scss diff --git a/src/plugins/discover/public/application/components/source_viewer/source_viewer.test.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer_source/source.test.tsx similarity index 89% rename from src/plugins/discover/public/application/components/source_viewer/source_viewer.test.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer_source/source.test.tsx index a98c2de6197d8..9b5b27fa979aa 100644 --- a/src/plugins/discover/public/application/components/source_viewer/source_viewer.test.tsx +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer_source/source.test.tsx @@ -9,17 +9,17 @@ import React from 'react'; import type { IndexPattern } from 'src/plugins/data/common'; import { mountWithIntl } from '@kbn/test/jest'; -import { SourceViewer } from './source_viewer'; -import * as hooks from '../../services/use_es_doc_search'; +import { DocViewerSource } from './source'; +import * as hooks from '../../../../utils/use_es_doc_search'; import * as useUiSettingHook from 'src/plugins/kibana_react/public/ui_settings/use_ui_setting'; import { EuiButton, EuiEmptyPrompt, EuiLoadingSpinner } from '@elastic/eui'; -import { JsonCodeEditorCommon } from '../json_code_editor/json_code_editor_common'; +import { JsonCodeEditorCommon } from '../../../../components/json_code_editor/json_code_editor_common'; -jest.mock('../../../kibana_services', () => ({ +jest.mock('../../../../kibana_services', () => ({ getServices: jest.fn(), })); -import { getServices } from '../../../kibana_services'; +import { getServices } from '../../../../kibana_services'; const mockIndexPattern = { getComputedFields: () => [], @@ -46,7 +46,7 @@ describe('Source Viewer component', () => { jest.spyOn(hooks, 'useEsDocSearch').mockImplementation(() => [0, null, () => {}]); const comp = mountWithIntl( - { jest.spyOn(hooks, 'useEsDocSearch').mockImplementation(() => [3, null, () => {}]); const comp = mountWithIntl( - { return false; }); const comp = mountWithIntl( - ); }; - -// Required for usage in React.lazy -// eslint-disable-next-line import/no-default-export -export default SourceViewer; diff --git a/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/index.ts b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/index.ts new file mode 100644 index 0000000000000..cfda31e12bb64 --- /dev/null +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/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 + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import { DocViewerTable } from './table'; + +// Required for usage in React.lazy +// eslint-disable-next-line import/no-default-export +export default DocViewerTable; diff --git a/src/plugins/discover/public/application/components/table/table.test.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table.test.tsx similarity index 98% rename from src/plugins/discover/public/application/components/table/table.test.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table.test.tsx index 176a1961378aa..5133ca46015a0 100644 --- a/src/plugins/discover/public/application/components/table/table.test.tsx +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table.test.tsx @@ -10,14 +10,14 @@ import React from 'react'; import { mountWithIntl } from '@kbn/test/jest'; import { findTestSubject } from '@elastic/eui/lib/test'; import { DocViewerTable, DocViewerTableProps } from './table'; -import { IndexPattern } from '../../../../../data/public'; -import { ElasticSearchHit } from '../../doc_views/doc_views_types'; +import { IndexPattern } from '../../../../../../data/public'; +import { ElasticSearchHit } from '../../doc_views_types'; -jest.mock('../../../kibana_services', () => ({ +jest.mock('../../../../kibana_services', () => ({ getServices: jest.fn(), })); -import { getServices } from '../../../kibana_services'; +import { getServices } from '../../../../kibana_services'; (getServices as jest.Mock).mockImplementation(() => ({ uiSettings: { diff --git a/src/plugins/discover/public/application/components/table/table.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table.tsx similarity index 85% rename from src/plugins/discover/public/application/components/table/table.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table.tsx index 78a6d9ddd3237..08cd0306f8759 100644 --- a/src/plugins/discover/public/application/components/table/table.tsx +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table.tsx @@ -8,20 +8,16 @@ import React, { useCallback, useMemo } from 'react'; import { EuiInMemoryTable } from '@elastic/eui'; -import { IndexPattern, IndexPatternField } from '../../../../../data/public'; -import { flattenHit } from '../../../../../data/common'; -import { SHOW_MULTIFIELDS } from '../../../../common'; -import { getServices } from '../../../kibana_services'; -import { isNestedFieldParent } from '../../apps/main/utils/nested_fields'; -import { - DocViewFilterFn, - ElasticSearchHit, - DocViewRenderProps, -} from '../../doc_views/doc_views_types'; +import { IndexPattern, IndexPatternField } from '../../../../../../data/public'; +import { flattenHit } from '../../../../../../data/common'; +import { SHOW_MULTIFIELDS } from '../../../../../common'; +import { getServices } from '../../../../kibana_services'; +import { DocViewFilterFn, ElasticSearchHit, DocViewRenderProps } from '../../doc_views_types'; import { ACTIONS_COLUMN, MAIN_COLUMNS } from './table_columns'; -import { getFieldsToShow } from '../../helpers/get_fields_to_show'; -import { getIgnoredReason, IgnoredReason } from '../../helpers/get_ignored_reason'; -import { formatFieldValue } from '../../helpers/format_value'; +import { getFieldsToShow } from '../../../../utils/get_fields_to_show'; +import { getIgnoredReason, IgnoredReason } from '../../../../utils/get_ignored_reason'; +import { formatFieldValue } from '../../../../utils/format_value'; +import { isNestedFieldParent } from '../../../../application/main/utils/nested_fields'; export interface DocViewerTableProps { columns?: string[]; @@ -151,7 +147,3 @@ export const DocViewerTable = ({ /> ); }; - -// Required for usage in React.lazy -// eslint-disable-next-line import/no-default-export -export default DocViewerTable; diff --git a/src/plugins/discover/public/application/components/table/table_cell_actions.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_cell_actions.tsx similarity index 93% rename from src/plugins/discover/public/application/components/table/table_cell_actions.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_cell_actions.tsx index e43a17448de2e..05a7056cf07e6 100644 --- a/src/plugins/discover/public/application/components/table/table_cell_actions.tsx +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_cell_actions.tsx @@ -11,8 +11,8 @@ import { DocViewTableRowBtnFilterRemove } from './table_row_btn_filter_remove'; import { DocViewTableRowBtnFilterExists } from './table_row_btn_filter_exists'; import { DocViewTableRowBtnToggleColumn } from './table_row_btn_toggle_column'; import { DocViewTableRowBtnFilterAdd } from './table_row_btn_filter_add'; -import { IndexPatternField } from '../../../../../data/public'; -import { DocViewFilterFn } from '../../doc_views/doc_views_types'; +import { IndexPatternField } from '../../../../../../data/public'; +import { DocViewFilterFn } from '../../doc_views_types'; interface TableActionsProps { field: string; diff --git a/src/plugins/discover/public/application/components/table/table_cell_value.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_cell_value.tsx similarity index 98% rename from src/plugins/discover/public/application/components/table/table_cell_value.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_cell_value.tsx index ebb4ea243fb25..88d6b30cc633e 100644 --- a/src/plugins/discover/public/application/components/table/table_cell_value.tsx +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_cell_value.tsx @@ -11,7 +11,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiTextColor, EuiToolTip } from '@e import classNames from 'classnames'; import React, { Fragment, useState } from 'react'; import { i18n } from '@kbn/i18n'; -import { IgnoredReason } from '../../helpers/get_ignored_reason'; +import { IgnoredReason } from '../../../../utils/get_ignored_reason'; import { FieldRecord } from './table'; import { DocViewTableRowBtnCollapse } from './table_row_btn_collapse'; diff --git a/src/plugins/discover/public/application/components/table/table_columns.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_columns.tsx similarity index 97% rename from src/plugins/discover/public/application/components/table/table_columns.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_columns.tsx index 9f502b4491977..0cd6a861b715b 100644 --- a/src/plugins/discover/public/application/components/table/table_columns.tsx +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_columns.tsx @@ -9,7 +9,7 @@ import { EuiBasicTableColumn, EuiText } from '@elastic/eui'; import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { FieldName } from '../field_name/field_name'; +import { FieldName } from '../../../../components/field_name/field_name'; import { FieldRecord } from './table'; import { TableActions } from './table_cell_actions'; import { TableFieldValue } from './table_cell_value'; diff --git a/src/plugins/discover/public/application/components/table/table_row_btn_collapse.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_row_btn_collapse.tsx similarity index 100% rename from src/plugins/discover/public/application/components/table/table_row_btn_collapse.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_row_btn_collapse.tsx diff --git a/src/plugins/discover/public/application/components/table/table_row_btn_filter_add.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_row_btn_filter_add.tsx similarity index 100% rename from src/plugins/discover/public/application/components/table/table_row_btn_filter_add.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_row_btn_filter_add.tsx diff --git a/src/plugins/discover/public/application/components/table/table_row_btn_filter_exists.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_row_btn_filter_exists.tsx similarity index 100% rename from src/plugins/discover/public/application/components/table/table_row_btn_filter_exists.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_row_btn_filter_exists.tsx diff --git a/src/plugins/discover/public/application/components/table/table_row_btn_filter_remove.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_row_btn_filter_remove.tsx similarity index 100% rename from src/plugins/discover/public/application/components/table/table_row_btn_filter_remove.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_row_btn_filter_remove.tsx index 4a14c269901d4..9875eb411d0e4 100644 --- a/src/plugins/discover/public/application/components/table/table_row_btn_filter_remove.tsx +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_row_btn_filter_remove.tsx @@ -8,8 +8,8 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiToolTip, EuiButtonIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { EuiToolTip, EuiButtonIcon } from '@elastic/eui'; export interface Props { onClick: () => void; diff --git a/src/plugins/discover/public/application/components/table/table_row_btn_toggle_column.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_row_btn_toggle_column.tsx similarity index 100% rename from src/plugins/discover/public/application/components/table/table_row_btn_toggle_column.tsx rename to src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_row_btn_toggle_column.tsx index cd5f73d47b1a1..dfaf6986022cc 100644 --- a/src/plugins/discover/public/application/components/table/table_row_btn_toggle_column.tsx +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer_table/table_row_btn_toggle_column.tsx @@ -8,8 +8,8 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiToolTip, EuiButtonIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { EuiToolTip, EuiButtonIcon } from '@elastic/eui'; export interface Props { active: boolean; diff --git a/src/plugins/discover/public/application/doc_views/doc_views_registry.ts b/src/plugins/discover/public/services/doc_views/doc_views_registry.ts similarity index 100% rename from src/plugins/discover/public/application/doc_views/doc_views_registry.ts rename to src/plugins/discover/public/services/doc_views/doc_views_registry.ts diff --git a/src/plugins/discover/public/application/doc_views/doc_views_types.ts b/src/plugins/discover/public/services/doc_views/doc_views_types.ts similarity index 100% rename from src/plugins/discover/public/application/doc_views/doc_views_types.ts rename to src/plugins/discover/public/services/doc_views/doc_views_types.ts diff --git a/src/plugins/discover/public/saved_searches/constants.ts b/src/plugins/discover/public/services/saved_searches/constants.ts similarity index 100% rename from src/plugins/discover/public/saved_searches/constants.ts rename to src/plugins/discover/public/services/saved_searches/constants.ts diff --git a/src/plugins/discover/public/saved_searches/get_saved_searches.test.ts b/src/plugins/discover/public/services/saved_searches/get_saved_searches.test.ts similarity index 94% rename from src/plugins/discover/public/saved_searches/get_saved_searches.test.ts rename to src/plugins/discover/public/services/saved_searches/get_saved_searches.test.ts index 560e16b12e5ed..1ac5f2d9653aa 100644 --- a/src/plugins/discover/public/saved_searches/get_saved_searches.test.ts +++ b/src/plugins/discover/public/services/saved_searches/get_saved_searches.test.ts @@ -5,11 +5,11 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import type { SavedObjectsStart } from '../../../../core/public'; -import type { DataPublicPluginStart } from '../../../data/public'; +import type { SavedObjectsStart } from 'kibana/public'; +import type { DataPublicPluginStart } from '../../../../data/public'; -import { savedObjectsServiceMock } from '../../../../core/public/mocks'; -import { dataPluginMock } from '../../../data/public/mocks'; +import { savedObjectsServiceMock } from '../../../../../core/public/mocks'; +import { dataPluginMock } from '../../../../data/public/mocks'; import { getSavedSearch } from './get_saved_searches'; diff --git a/src/plugins/discover/public/saved_searches/get_saved_searches.ts b/src/plugins/discover/public/services/saved_searches/get_saved_searches.ts similarity index 88% rename from src/plugins/discover/public/saved_searches/get_saved_searches.ts rename to src/plugins/discover/public/services/saved_searches/get_saved_searches.ts index 32c50f691fe42..b4b9ecc89acf5 100644 --- a/src/plugins/discover/public/saved_searches/get_saved_searches.ts +++ b/src/plugins/discover/public/services/saved_searches/get_saved_searches.ts @@ -6,16 +6,16 @@ * Side Public License, v 1. */ -import type { SavedObjectsStart } from '../../../../core/public'; -import type { DataPublicPluginStart } from '../../../data/public'; +import type { SavedObjectsStart } from 'kibana/public'; +import type { DataPublicPluginStart } from '../../../../data/public'; import type { SavedSearchAttributes, SavedSearch } from './types'; import { SAVED_SEARCH_TYPE } from './constants'; import { fromSavedSearchAttributes } from './saved_searches_utils'; -import { injectSearchSourceReferences, parseSearchSourceJSON } from '../../../data/public'; -import { SavedObjectNotFound } from '../../../kibana_utils/public'; +import { injectSearchSourceReferences, parseSearchSourceJSON } from '../../../../data/public'; +import { SavedObjectNotFound } from '../../../../kibana_utils/public'; -import type { SpacesApi } from '../../../../../x-pack/plugins/spaces/public'; +import type { SpacesApi } from '../../../../../../x-pack/plugins/spaces/public'; interface GetSavedSearchDependencies { search: DataPublicPluginStart['search']; diff --git a/src/plugins/discover/public/saved_searches/index.ts b/src/plugins/discover/public/services/saved_searches/index.ts similarity index 100% rename from src/plugins/discover/public/saved_searches/index.ts rename to src/plugins/discover/public/services/saved_searches/index.ts diff --git a/src/plugins/discover/public/saved_searches/save_saved_searches.test.ts b/src/plugins/discover/public/services/saved_searches/save_saved_searches.test.ts similarity index 93% rename from src/plugins/discover/public/saved_searches/save_saved_searches.test.ts rename to src/plugins/discover/public/services/saved_searches/save_saved_searches.test.ts index eabbfe7f9419f..fd6777155a53b 100644 --- a/src/plugins/discover/public/saved_searches/save_saved_searches.test.ts +++ b/src/plugins/discover/public/services/saved_searches/save_saved_searches.test.ts @@ -6,10 +6,10 @@ * Side Public License, v 1. */ -import type { SavedObjectsStart } from '../../../../core/public'; +import type { SavedObjectsStart } from 'kibana/public'; -import { savedObjectsServiceMock } from '../../../../core/public/mocks'; -import { dataPluginMock } from '../../../data/public/mocks'; +import { savedObjectsServiceMock } from '../../../../../core/public/mocks'; +import { dataPluginMock } from '../../../../data/public/mocks'; import { saveSavedSearch } from './save_saved_searches'; import type { SavedSearch } from './types'; diff --git a/src/plugins/discover/public/saved_searches/save_saved_searches.ts b/src/plugins/discover/public/services/saved_searches/save_saved_searches.ts similarity index 100% rename from src/plugins/discover/public/saved_searches/save_saved_searches.ts rename to src/plugins/discover/public/services/saved_searches/save_saved_searches.ts diff --git a/src/plugins/discover/public/saved_searches/saved_search_alias_match_redirect.test.ts b/src/plugins/discover/public/services/saved_searches/saved_search_alias_match_redirect.test.ts similarity index 95% rename from src/plugins/discover/public/saved_searches/saved_search_alias_match_redirect.test.ts rename to src/plugins/discover/public/services/saved_searches/saved_search_alias_match_redirect.test.ts index 0a871061d2b19..51f1131122553 100644 --- a/src/plugins/discover/public/saved_searches/saved_search_alias_match_redirect.test.ts +++ b/src/plugins/discover/public/services/saved_searches/saved_search_alias_match_redirect.test.ts @@ -12,7 +12,7 @@ import type { History } from 'history'; import { useSavedSearchAliasMatchRedirect } from './saved_search_alias_match_redirect'; import type { SavedSearch } from './types'; -import { spacesPluginMock } from '../../../../../x-pack/plugins/spaces/public/mocks'; +import { spacesPluginMock } from '../../../../../../x-pack/plugins/spaces/public/mocks'; describe('useSavedSearchAliasMatchRedirect', () => { let spaces: ReturnType; diff --git a/src/plugins/discover/public/saved_searches/saved_search_alias_match_redirect.ts b/src/plugins/discover/public/services/saved_searches/saved_search_alias_match_redirect.ts similarity index 94% rename from src/plugins/discover/public/saved_searches/saved_search_alias_match_redirect.ts rename to src/plugins/discover/public/services/saved_searches/saved_search_alias_match_redirect.ts index 3a88c1a2b1989..2d49ebeb8b2de 100644 --- a/src/plugins/discover/public/saved_searches/saved_search_alias_match_redirect.ts +++ b/src/plugins/discover/public/services/saved_searches/saved_search_alias_match_redirect.ts @@ -12,7 +12,7 @@ import { i18n } from '@kbn/i18n'; import { getSavedSearchUrl } from './saved_searches_utils'; import type { SavedSearch } from './types'; -import type { SpacesApi } from '../../../../../x-pack/plugins/spaces/public'; +import type { SpacesApi } from '../../../../../../x-pack/plugins/spaces/public'; interface SavedSearchAliasMatchRedirectProps { savedSearch?: SavedSearch; diff --git a/src/plugins/discover/public/saved_searches/saved_search_url_conflict_callout.test.tsx b/src/plugins/discover/public/services/saved_searches/saved_search_url_conflict_callout.test.tsx similarity index 95% rename from src/plugins/discover/public/saved_searches/saved_search_url_conflict_callout.test.tsx rename to src/plugins/discover/public/services/saved_searches/saved_search_url_conflict_callout.test.tsx index c92c15e771f64..0aac9aea62192 100644 --- a/src/plugins/discover/public/saved_searches/saved_search_url_conflict_callout.test.tsx +++ b/src/plugins/discover/public/services/saved_searches/saved_search_url_conflict_callout.test.tsx @@ -13,7 +13,7 @@ import { mountWithIntl } from '@kbn/test/jest'; import { SavedSearchURLConflictCallout } from './saved_search_url_conflict_callout'; import type { SavedSearch } from './types'; -import { spacesPluginMock } from '../../../../../x-pack/plugins/spaces/public/mocks'; +import { spacesPluginMock } from '../../../../../../x-pack/plugins/spaces/public/mocks'; describe('SavedSearchURLConflictCallout', () => { let spaces: ReturnType; diff --git a/src/plugins/discover/public/saved_searches/saved_search_url_conflict_callout.ts b/src/plugins/discover/public/services/saved_searches/saved_search_url_conflict_callout.ts similarity index 94% rename from src/plugins/discover/public/saved_searches/saved_search_url_conflict_callout.ts rename to src/plugins/discover/public/services/saved_searches/saved_search_url_conflict_callout.ts index fd07126c496cf..4a13b56a5e8d7 100644 --- a/src/plugins/discover/public/saved_searches/saved_search_url_conflict_callout.ts +++ b/src/plugins/discover/public/services/saved_searches/saved_search_url_conflict_callout.ts @@ -11,7 +11,7 @@ import type { History } from 'history'; import { getSavedSearchUrl } from './saved_searches_utils'; import type { SavedSearch } from './types'; -import type { SpacesApi } from '../../../../../x-pack/plugins/spaces/public'; +import type { SpacesApi } from '../../../../../../x-pack/plugins/spaces/public'; interface SavedSearchURLConflictCalloutProps { savedSearch?: SavedSearch; diff --git a/src/plugins/discover/public/saved_searches/saved_searches_utils.test.ts b/src/plugins/discover/public/services/saved_searches/saved_searches_utils.test.ts similarity index 98% rename from src/plugins/discover/public/saved_searches/saved_searches_utils.test.ts rename to src/plugins/discover/public/services/saved_searches/saved_searches_utils.test.ts index 82510340f30f1..3d7d053bd1ec5 100644 --- a/src/plugins/discover/public/saved_searches/saved_searches_utils.test.ts +++ b/src/plugins/discover/public/services/saved_searches/saved_searches_utils.test.ts @@ -14,7 +14,7 @@ import { throwErrorOnSavedSearchUrlConflict, } from './saved_searches_utils'; -import { createSearchSourceMock } from '../../../data/public/mocks'; +import { createSearchSourceMock } from '../../../../data/public/mocks'; import type { SavedSearchAttributes, SavedSearch } from './types'; diff --git a/src/plugins/discover/public/saved_searches/saved_searches_utils.ts b/src/plugins/discover/public/services/saved_searches/saved_searches_utils.ts similarity index 100% rename from src/plugins/discover/public/saved_searches/saved_searches_utils.ts rename to src/plugins/discover/public/services/saved_searches/saved_searches_utils.ts diff --git a/src/plugins/discover/public/saved_searches/types.ts b/src/plugins/discover/public/services/saved_searches/types.ts similarity index 84% rename from src/plugins/discover/public/saved_searches/types.ts rename to src/plugins/discover/public/services/saved_searches/types.ts index b3a67ea57e769..4247f68ba8194 100644 --- a/src/plugins/discover/public/saved_searches/types.ts +++ b/src/plugins/discover/public/services/saved_searches/types.ts @@ -6,9 +6,9 @@ * Side Public License, v 1. */ -import type { ISearchSource } from '../../../data/public'; -import { DiscoverGridSettingsColumn } from '../application/components/discover_grid/types'; -import { VIEW_MODE } from '../application/apps/main/components/view_mode_toggle'; +import type { ISearchSource } from '../../../../data/public'; +import { DiscoverGridSettingsColumn } from '../../components/discover_grid/types'; +import { VIEW_MODE } from '../../components/view_mode_toggle'; /** @internal **/ export interface SavedSearchAttributes { diff --git a/src/plugins/discover/public/application/helpers/breadcrumbs.ts b/src/plugins/discover/public/utils/breadcrumbs.ts similarity index 96% rename from src/plugins/discover/public/application/helpers/breadcrumbs.ts rename to src/plugins/discover/public/utils/breadcrumbs.ts index fe420328a3171..4a3df34e2da75 100644 --- a/src/plugins/discover/public/application/helpers/breadcrumbs.ts +++ b/src/plugins/discover/public/utils/breadcrumbs.ts @@ -8,7 +8,7 @@ import { ChromeStart } from 'kibana/public'; import { i18n } from '@kbn/i18n'; -import { SavedSearch } from '../../saved_searches'; +import { SavedSearch } from '../services/saved_searches'; export function getRootBreadcrumbs() { return [ diff --git a/src/plugins/discover/public/application/helpers/columns.test.ts b/src/plugins/discover/public/utils/columns.test.ts similarity index 91% rename from src/plugins/discover/public/application/helpers/columns.test.ts rename to src/plugins/discover/public/utils/columns.test.ts index 6b6125193b5f3..dc6677680f0ed 100644 --- a/src/plugins/discover/public/application/helpers/columns.test.ts +++ b/src/plugins/discover/public/utils/columns.test.ts @@ -7,8 +7,8 @@ */ import { getDisplayedColumns } from './columns'; -import { indexPatternWithTimefieldMock } from '../../__mocks__/index_pattern_with_timefield'; -import { indexPatternMock } from '../../__mocks__/index_pattern'; +import { indexPatternWithTimefieldMock } from '../__mocks__/index_pattern_with_timefield'; +import { indexPatternMock } from '../__mocks__/index_pattern'; describe('getDisplayedColumns', () => { test('returns default columns given a index pattern without timefield', async () => { diff --git a/src/plugins/discover/public/application/helpers/columns.ts b/src/plugins/discover/public/utils/columns.ts similarity index 95% rename from src/plugins/discover/public/application/helpers/columns.ts rename to src/plugins/discover/public/utils/columns.ts index 6e77717c5cf05..6c32ac509e63b 100644 --- a/src/plugins/discover/public/application/helpers/columns.ts +++ b/src/plugins/discover/public/utils/columns.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { IndexPattern } from '../../../../data/common'; +import { IndexPattern } from '../../../data/common'; // We store this outside the function as a constant, so we're not creating a new array every time // the function is returning this. A changing array might cause the data grid to think it got diff --git a/src/plugins/discover/public/application/helpers/format_hit.test.ts b/src/plugins/discover/public/utils/format_hit.test.ts similarity index 89% rename from src/plugins/discover/public/application/helpers/format_hit.test.ts rename to src/plugins/discover/public/utils/format_hit.test.ts index ebf5078238ccf..325903ffebdd3 100644 --- a/src/plugins/discover/public/application/helpers/format_hit.test.ts +++ b/src/plugins/discover/public/utils/format_hit.test.ts @@ -7,13 +7,13 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { indexPatternMock as dataViewMock } from '../../__mocks__/index_pattern'; +import { indexPatternMock as dataViewMock } from '../__mocks__/index_pattern'; import { formatHit } from './format_hit'; -import { discoverServiceMock } from '../../__mocks__/services'; -import { MAX_DOC_FIELDS_DISPLAYED } from '../../../common'; +import { discoverServiceMock } from '../__mocks__/services'; +import { MAX_DOC_FIELDS_DISPLAYED } from '../../common'; -jest.mock('../../kibana_services', () => ({ - getServices: () => jest.requireActual('../../__mocks__/services').discoverServiceMock, +jest.mock('../kibana_services', () => ({ + getServices: () => jest.requireActual('../__mocks__/services').discoverServiceMock, })); describe('formatHit', () => { diff --git a/src/plugins/discover/public/application/helpers/format_hit.ts b/src/plugins/discover/public/utils/format_hit.ts similarity index 94% rename from src/plugins/discover/public/application/helpers/format_hit.ts rename to src/plugins/discover/public/utils/format_hit.ts index 1101439515523..b1bbfcd5aa878 100644 --- a/src/plugins/discover/public/application/helpers/format_hit.ts +++ b/src/plugins/discover/public/utils/format_hit.ts @@ -7,9 +7,9 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { DataView, flattenHit } from '../../../../data/common'; -import { MAX_DOC_FIELDS_DISPLAYED } from '../../../common'; -import { getServices } from '../../kibana_services'; +import { DataView, flattenHit } from '../../../data/common'; +import { MAX_DOC_FIELDS_DISPLAYED } from '../../common'; +import { getServices } from '../kibana_services'; import { formatFieldValue } from './format_value'; const formattedHitCache = new WeakMap(); diff --git a/src/plugins/discover/public/application/helpers/format_value.test.ts b/src/plugins/discover/public/utils/format_value.test.ts similarity index 91% rename from src/plugins/discover/public/application/helpers/format_value.test.ts rename to src/plugins/discover/public/utils/format_value.test.ts index 76d95c08e4a19..4684547b7cf3e 100644 --- a/src/plugins/discover/public/application/helpers/format_value.test.ts +++ b/src/plugins/discover/public/utils/format_value.test.ts @@ -6,13 +6,13 @@ * Side Public License, v 1. */ -import type { FieldFormat } from '../../../../field_formats/common'; -import { indexPatternMock } from '../../__mocks__/index_pattern'; +import type { FieldFormat } from '../../../field_formats/common'; +import { indexPatternMock } from '../__mocks__/index_pattern'; import { formatFieldValue } from './format_value'; -import { getServices } from '../../kibana_services'; +import { getServices } from '../kibana_services'; -jest.mock('../../kibana_services', () => { +jest.mock('../kibana_services', () => { const services = { fieldFormats: { getDefaultInstance: jest.fn( diff --git a/src/plugins/discover/public/application/helpers/format_value.ts b/src/plugins/discover/public/utils/format_value.ts similarity index 95% rename from src/plugins/discover/public/application/helpers/format_value.ts rename to src/plugins/discover/public/utils/format_value.ts index 933309d6dcf8e..7a2a67b063191 100644 --- a/src/plugins/discover/public/application/helpers/format_value.ts +++ b/src/plugins/discover/public/utils/format_value.ts @@ -7,8 +7,8 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { DataView, DataViewField, KBN_FIELD_TYPES } from '../../../../data/common'; -import { getServices } from '../../kibana_services'; +import { DataView, DataViewField, KBN_FIELD_TYPES } from '../../../data/common'; +import { getServices } from '../kibana_services'; /** * Formats the value of a specific field using the appropriate field formatter if available diff --git a/src/plugins/discover/public/application/helpers/get_context_url.test.ts b/src/plugins/discover/public/utils/get_context_url.test.ts similarity index 94% rename from src/plugins/discover/public/application/helpers/get_context_url.test.ts rename to src/plugins/discover/public/utils/get_context_url.test.ts index 97d31ca43142d..d6d1db5ca393b 100644 --- a/src/plugins/discover/public/application/helpers/get_context_url.test.ts +++ b/src/plugins/discover/public/utils/get_context_url.test.ts @@ -7,7 +7,7 @@ */ import { getContextUrl } from './get_context_url'; -import { FilterManager } from '../../../../data/public/query/filter_manager'; +import { FilterManager } from '../../../data/public/query/filter_manager'; const filterManager = { getGlobalFilters: () => [], getAppFilters: () => [], diff --git a/src/plugins/discover/public/application/helpers/get_context_url.tsx b/src/plugins/discover/public/utils/get_context_url.tsx similarity index 87% rename from src/plugins/discover/public/application/helpers/get_context_url.tsx rename to src/plugins/discover/public/utils/get_context_url.tsx index 057f8bc2afc52..68c0e935f17e9 100644 --- a/src/plugins/discover/public/application/helpers/get_context_url.tsx +++ b/src/plugins/discover/public/utils/get_context_url.tsx @@ -8,9 +8,9 @@ import { stringify } from 'query-string'; import rison from 'rison-node'; -import { url } from '../../../../kibana_utils/common'; -import { esFilters, FilterManager } from '../../../../data/public'; -import { DiscoverServices } from '../../build_services'; +import { url } from '../../../kibana_utils/common'; +import { esFilters, FilterManager } from '../../../data/public'; +import { DiscoverServices } from '../build_services'; /** * Helper function to generate an URL to a document in Discover's context view diff --git a/src/plugins/discover/public/application/helpers/get_fields_to_show.test.ts b/src/plugins/discover/public/utils/get_fields_to_show.test.ts similarity index 97% rename from src/plugins/discover/public/application/helpers/get_fields_to_show.test.ts rename to src/plugins/discover/public/utils/get_fields_to_show.test.ts index 13c2dbaac6124..5e61a7aec01c0 100644 --- a/src/plugins/discover/public/application/helpers/get_fields_to_show.test.ts +++ b/src/plugins/discover/public/utils/get_fields_to_show.test.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { IndexPattern, IndexPatternField } from '../../../../data/common'; +import { IndexPattern, IndexPatternField } from '../../../data/common'; import { getFieldsToShow } from './get_fields_to_show'; describe('get fields to show', () => { diff --git a/src/plugins/discover/public/application/helpers/get_fields_to_show.ts b/src/plugins/discover/public/utils/get_fields_to_show.ts similarity index 94% rename from src/plugins/discover/public/application/helpers/get_fields_to_show.ts rename to src/plugins/discover/public/utils/get_fields_to_show.ts index 5e3f0c0b60057..9167165c2b08f 100644 --- a/src/plugins/discover/public/application/helpers/get_fields_to_show.ts +++ b/src/plugins/discover/public/utils/get_fields_to_show.ts @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { IndexPattern, getFieldSubtypeMulti } from '../../../../data/common'; +import { IndexPattern, getFieldSubtypeMulti } from '../../../data/common'; export const getFieldsToShow = ( fields: string[], diff --git a/src/plugins/discover/public/application/helpers/get_ignored_reason.test.ts b/src/plugins/discover/public/utils/get_ignored_reason.test.ts similarity index 96% rename from src/plugins/discover/public/application/helpers/get_ignored_reason.test.ts rename to src/plugins/discover/public/utils/get_ignored_reason.test.ts index 13632ca5ed901..82af0079702da 100644 --- a/src/plugins/discover/public/application/helpers/get_ignored_reason.test.ts +++ b/src/plugins/discover/public/utils/get_ignored_reason.test.ts @@ -7,7 +7,7 @@ */ import { getIgnoredReason, IgnoredReason } from './get_ignored_reason'; -import { DataViewField, KBN_FIELD_TYPES } from '../../../../data/common'; +import { DataViewField, KBN_FIELD_TYPES } from '../../../data/common'; function field(params: Partial): DataViewField { return { diff --git a/src/plugins/discover/public/application/helpers/get_ignored_reason.ts b/src/plugins/discover/public/utils/get_ignored_reason.ts similarity index 95% rename from src/plugins/discover/public/application/helpers/get_ignored_reason.ts rename to src/plugins/discover/public/utils/get_ignored_reason.ts index bf8df6e000d4c..901765b26b918 100644 --- a/src/plugins/discover/public/application/helpers/get_ignored_reason.ts +++ b/src/plugins/discover/public/utils/get_ignored_reason.ts @@ -7,7 +7,7 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { DataViewField, KBN_FIELD_TYPES } from '../../../../data/common'; +import { DataViewField, KBN_FIELD_TYPES } from '../../../data/common'; export enum IgnoredReason { IGNORE_ABOVE = 'ignore_above', diff --git a/src/plugins/discover/public/application/apps/main/utils/get_sharing_data.test.ts b/src/plugins/discover/public/utils/get_sharing_data.test.ts similarity index 93% rename from src/plugins/discover/public/application/apps/main/utils/get_sharing_data.test.ts rename to src/plugins/discover/public/utils/get_sharing_data.test.ts index 9b518c23a5f89..fda4e731191e7 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_sharing_data.test.ts +++ b/src/plugins/discover/public/utils/get_sharing_data.test.ts @@ -8,11 +8,11 @@ import { Capabilities, IUiSettingsClient } from 'kibana/public'; import type { IndexPattern } from 'src/plugins/data/public'; -import type { DiscoverServices } from '../../../../build_services'; -import { dataPluginMock } from '../../../../../../data/public/mocks'; -import { createSearchSourceMock } from '../../../../../../data/common/search/search_source/mocks'; -import { DOC_HIDE_TIME_COLUMN_SETTING, SORT_DEFAULT_ORDER_SETTING } from '../../../../../common'; -import { indexPatternMock } from '../../../../__mocks__/index_pattern'; +import type { DiscoverServices } from '../build_services'; +import { dataPluginMock } from '../../../data/public/mocks'; +import { createSearchSourceMock } from '../../../data/common/search/search_source/mocks'; +import { DOC_HIDE_TIME_COLUMN_SETTING, SORT_DEFAULT_ORDER_SETTING } from '../../common'; +import { indexPatternMock } from '../__mocks__/index_pattern'; import { getSharingData, showPublicUrlSwitch } from './get_sharing_data'; describe('getSharingData', () => { diff --git a/src/plugins/discover/public/application/apps/main/utils/get_sharing_data.ts b/src/plugins/discover/public/utils/get_sharing_data.ts similarity index 92% rename from src/plugins/discover/public/application/apps/main/utils/get_sharing_data.ts rename to src/plugins/discover/public/utils/get_sharing_data.ts index 437d4fda666fc..a8e210c980810 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_sharing_data.ts +++ b/src/plugins/discover/public/utils/get_sharing_data.ts @@ -7,13 +7,13 @@ */ import type { Capabilities } from 'kibana/public'; -import type { IUiSettingsClient } from 'src/core/public'; +import type { IUiSettingsClient } from 'kibana/public'; import type { DataPublicPluginStart } from 'src/plugins/data/public'; import type { ISearchSource, SearchSourceFields } from 'src/plugins/data/common'; -import { DOC_HIDE_TIME_COLUMN_SETTING, SORT_DEFAULT_ORDER_SETTING } from '../../../../../common'; -import type { SavedSearch, SortOrder } from '../../../../saved_searches'; +import { DOC_HIDE_TIME_COLUMN_SETTING, SORT_DEFAULT_ORDER_SETTING } from '../../common'; +import type { SavedSearch, SortOrder } from '../services/saved_searches'; import { getSortForSearchSource } from '../components/doc_table'; -import { AppState } from '../services/discover_state'; +import { AppState } from '../application/main/services/discover_state'; /** * Preparing data to share the current state as link or CSV/Report diff --git a/src/plugins/discover/public/application/helpers/get_single_doc_url.ts b/src/plugins/discover/public/utils/get_single_doc_url.ts similarity index 100% rename from src/plugins/discover/public/application/helpers/get_single_doc_url.ts rename to src/plugins/discover/public/utils/get_single_doc_url.ts diff --git a/src/plugins/discover/public/shared/index.ts b/src/plugins/discover/public/utils/index.ts similarity index 79% rename from src/plugins/discover/public/shared/index.ts rename to src/plugins/discover/public/utils/index.ts index 7471e1293baa0..9a3e709fc71e4 100644 --- a/src/plugins/discover/public/shared/index.ts +++ b/src/plugins/discover/public/utils/index.ts @@ -5,12 +5,9 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ - /* * Allows the getSharingData function to be lazy loadable */ export async function loadSharingDataHelpers() { - return await import('../application/apps/main/utils/get_sharing_data'); + return await import('./get_sharing_data'); } - -export { DeferredSpinner } from './components'; diff --git a/src/plugins/discover/public/application/helpers/migrate_legacy_query.ts b/src/plugins/discover/public/utils/migrate_legacy_query.ts similarity index 100% rename from src/plugins/discover/public/application/helpers/migrate_legacy_query.ts rename to src/plugins/discover/public/utils/migrate_legacy_query.ts diff --git a/src/plugins/discover/public/application/helpers/popularize_field.test.ts b/src/plugins/discover/public/utils/popularize_field.test.ts similarity index 97% rename from src/plugins/discover/public/application/helpers/popularize_field.test.ts rename to src/plugins/discover/public/utils/popularize_field.test.ts index 91673fd17d3be..066b12b9603e4 100644 --- a/src/plugins/discover/public/application/helpers/popularize_field.test.ts +++ b/src/plugins/discover/public/utils/popularize_field.test.ts @@ -7,7 +7,7 @@ */ import { Capabilities } from 'kibana/public'; -import { IndexPattern, IndexPatternsService } from '../../../../data/public'; +import { IndexPattern, IndexPatternsService } from '../../../data/public'; import { popularizeField } from './popularize_field'; const capabilities = { diff --git a/src/plugins/discover/public/application/helpers/popularize_field.ts b/src/plugins/discover/public/utils/popularize_field.ts similarity index 92% rename from src/plugins/discover/public/application/helpers/popularize_field.ts rename to src/plugins/discover/public/utils/popularize_field.ts index 90968dd7c3d58..18e720001edca 100644 --- a/src/plugins/discover/public/application/helpers/popularize_field.ts +++ b/src/plugins/discover/public/utils/popularize_field.ts @@ -7,7 +7,7 @@ */ import type { Capabilities } from 'kibana/public'; -import { IndexPattern, IndexPatternsContract } from '../../../../data/public'; +import { IndexPattern, IndexPatternsContract } from '../../../data/public'; async function popularizeField( indexPattern: IndexPattern, diff --git a/src/plugins/discover/public/application/helpers/state_helpers.ts b/src/plugins/discover/public/utils/state_helpers.ts similarity index 98% rename from src/plugins/discover/public/application/helpers/state_helpers.ts rename to src/plugins/discover/public/utils/state_helpers.ts index bb64f823d61a6..e50cd87ad82ee 100644 --- a/src/plugins/discover/public/application/helpers/state_helpers.ts +++ b/src/plugins/discover/public/utils/state_helpers.ts @@ -8,7 +8,7 @@ import { IUiSettingsClient } from 'kibana/public'; import { isEqual } from 'lodash'; -import { SEARCH_FIELDS_FROM_SOURCE, DEFAULT_COLUMNS_SETTING } from '../../../common'; +import { SEARCH_FIELDS_FROM_SOURCE, DEFAULT_COLUMNS_SETTING } from '../../common'; /** * Makes sure the current state is not referencing the source column when using the fields api diff --git a/src/plugins/discover/public/application/helpers/truncate_styles.ts b/src/plugins/discover/public/utils/truncate_styles.ts similarity index 100% rename from src/plugins/discover/public/application/helpers/truncate_styles.ts rename to src/plugins/discover/public/utils/truncate_styles.ts diff --git a/src/plugins/discover/public/application/helpers/use_data_grid_columns.test.tsx b/src/plugins/discover/public/utils/use_data_grid_columns.test.tsx similarity index 86% rename from src/plugins/discover/public/application/helpers/use_data_grid_columns.test.tsx rename to src/plugins/discover/public/utils/use_data_grid_columns.test.tsx index abb2138e882b1..d09e9d8d1c6ba 100644 --- a/src/plugins/discover/public/application/helpers/use_data_grid_columns.test.tsx +++ b/src/plugins/discover/public/utils/use_data_grid_columns.test.tsx @@ -8,11 +8,11 @@ import { renderHook } from '@testing-library/react-hooks'; import { useColumns } from './use_data_grid_columns'; -import { indexPatternMock } from '../../__mocks__/index_pattern'; -import { configMock } from '../../__mocks__/config'; -import { indexPatternsMock } from '../../__mocks__/index_patterns'; -import { AppState } from '../apps/context/services/context_state'; -import { Capabilities } from '../../../../../core/types'; +import { indexPatternMock } from '../__mocks__/index_pattern'; +import { configMock } from '../__mocks__/config'; +import { indexPatternsMock } from '../__mocks__/index_patterns'; +import { AppState } from '../application/context/services/context_state'; +import { Capabilities } from '../../../../core/types'; describe('useColumns', () => { const defaultProps = { diff --git a/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts b/src/plugins/discover/public/utils/use_data_grid_columns.ts similarity index 90% rename from src/plugins/discover/public/application/helpers/use_data_grid_columns.ts rename to src/plugins/discover/public/utils/use_data_grid_columns.ts index 888d67e2aaff3..09b296ce8138d 100644 --- a/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts +++ b/src/plugins/discover/public/utils/use_data_grid_columns.ts @@ -13,12 +13,12 @@ import { Capabilities, IUiSettingsClient } from 'kibana/public'; import { AppState as DiscoverState, GetStateReturn as DiscoverGetStateReturn, -} from '../apps/main/services/discover_state'; +} from '../application/main/services/discover_state'; import { AppState as ContextState, GetStateReturn as ContextGetStateReturn, -} from '../apps/context/services/context_state'; -import { getStateColumnActions } from '../apps/main/components/doc_table/actions/columns'; +} from '../application/context/services/context_state'; +import { getStateColumnActions } from '../components/doc_table/actions/columns'; interface UseColumnsProps { capabilities: Capabilities; diff --git a/src/plugins/discover/public/application/services/use_es_doc_search.test.tsx b/src/plugins/discover/public/utils/use_es_doc_search.test.tsx similarity index 96% rename from src/plugins/discover/public/application/services/use_es_doc_search.test.tsx rename to src/plugins/discover/public/utils/use_es_doc_search.test.tsx index ca57b470b471a..57538441a2bcc 100644 --- a/src/plugins/discover/public/application/services/use_es_doc_search.test.tsx +++ b/src/plugins/discover/public/utils/use_es_doc_search.test.tsx @@ -10,13 +10,13 @@ import { renderHook } from '@testing-library/react-hooks'; import { buildSearchBody, useEsDocSearch } from './use_es_doc_search'; import { Observable } from 'rxjs'; import { IndexPattern } from 'src/plugins/data/common'; -import { DocProps } from '../apps/doc/components/doc'; -import { ElasticRequestState } from '../apps/doc/types'; -import { SEARCH_FIELDS_FROM_SOURCE as mockSearchFieldsFromSource } from '../../../common'; +import { DocProps } from '../application/doc/components/doc'; +import { ElasticRequestState } from '../application/doc/types'; +import { SEARCH_FIELDS_FROM_SOURCE as mockSearchFieldsFromSource } from '../../common'; const mockSearchResult = new Observable(); -jest.mock('../../kibana_services', () => ({ +jest.mock('../kibana_services', () => ({ getServices: () => ({ data: { search: { diff --git a/src/plugins/discover/public/application/services/use_es_doc_search.ts b/src/plugins/discover/public/utils/use_es_doc_search.ts similarity index 87% rename from src/plugins/discover/public/application/services/use_es_doc_search.ts rename to src/plugins/discover/public/utils/use_es_doc_search.ts index fa7dce9c7e0a4..10c97c53b3fb3 100644 --- a/src/plugins/discover/public/application/services/use_es_doc_search.ts +++ b/src/plugins/discover/public/utils/use_es_doc_search.ts @@ -8,12 +8,12 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { IndexPattern } from '../../../../data/common'; -import { DocProps } from '../apps/doc/components/doc'; -import { ElasticRequestState } from '../apps/doc/types'; -import { ElasticSearchHit } from '../doc_views/doc_views_types'; -import { getServices } from '../../kibana_services'; -import { SEARCH_FIELDS_FROM_SOURCE } from '../../../common'; +import { IndexPattern } from '../../../data/common'; +import { DocProps } from '../application/doc/components/doc'; +import { ElasticRequestState } from '../application/doc/types'; +import { ElasticSearchHit } from '../services/doc_views/doc_views_types'; +import { getServices } from '../kibana_services'; +import { SEARCH_FIELDS_FROM_SOURCE } from '../../common'; type RequestBody = Pick; @@ -66,7 +66,7 @@ export function useEsDocSearch({ index, indexPattern, requestSource, -}: DocProps): [ElasticRequestState, ElasticSearchHit | null | null, () => void] { +}: DocProps): [ElasticRequestState, ElasticSearchHit | null, () => void] { const [status, setStatus] = useState(ElasticRequestState.Loading); const [hit, setHit] = useState(null); const { data, uiSettings } = useMemo(() => getServices(), []); diff --git a/src/plugins/discover/public/application/helpers/use_index_pattern.test.tsx b/src/plugins/discover/public/utils/use_index_pattern.test.tsx similarity index 89% rename from src/plugins/discover/public/application/helpers/use_index_pattern.test.tsx rename to src/plugins/discover/public/utils/use_index_pattern.test.tsx index dfc54d8630742..591478ec371fb 100644 --- a/src/plugins/discover/public/application/helpers/use_index_pattern.test.tsx +++ b/src/plugins/discover/public/utils/use_index_pattern.test.tsx @@ -6,8 +6,8 @@ * Side Public License, v 1. */ import { useIndexPattern } from './use_index_pattern'; -import { indexPatternMock } from '../../__mocks__/index_pattern'; -import { indexPatternsMock } from '../../__mocks__/index_patterns'; +import { indexPatternMock } from '../__mocks__/index_pattern'; +import { indexPatternsMock } from '../__mocks__/index_patterns'; import { renderHook } from '@testing-library/react-hooks'; describe('Use Index Pattern', () => { diff --git a/src/plugins/discover/public/application/helpers/use_index_pattern.tsx b/src/plugins/discover/public/utils/use_index_pattern.tsx similarity index 92% rename from src/plugins/discover/public/application/helpers/use_index_pattern.tsx rename to src/plugins/discover/public/utils/use_index_pattern.tsx index 374f83cbbfe72..3a87d21587fb7 100644 --- a/src/plugins/discover/public/application/helpers/use_index_pattern.tsx +++ b/src/plugins/discover/public/utils/use_index_pattern.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ import { useEffect, useState } from 'react'; -import { IndexPattern, IndexPatternsContract } from '../../../../data/common'; +import { IndexPattern, IndexPatternsContract } from '../../../data/common'; export const useIndexPattern = (indexPatterns: IndexPatternsContract, indexPatternId: string) => { const [indexPattern, setIndexPattern] = useState(undefined); diff --git a/src/plugins/expressions/common/expression_functions/specs/font.ts b/src/plugins/expressions/common/expression_functions/specs/font.ts index 3d189a68119d5..628685aa7338c 100644 --- a/src/plugins/expressions/common/expression_functions/specs/font.ts +++ b/src/plugins/expressions/common/expression_functions/specs/font.ts @@ -9,7 +9,15 @@ import { i18n } from '@kbn/i18n'; import { ExpressionFunctionDefinition } from '../types'; import { openSans, FontLabel as FontFamily } from '../../fonts'; -import { CSSStyle, FontStyle, FontWeight, Style, TextAlignment, TextDecoration } from '../../types'; +import { + CSSStyle, + FontSizeUnit, + FontStyle, + FontWeight, + Style, + TextAlignment, + TextDecoration, +} from '../../types'; const dashify = (str: string) => { return str @@ -39,6 +47,7 @@ export interface FontArguments { size?: number; underline?: boolean; weight?: FontWeight; + sizeUnit?: string; } export type ExpressionFunctionFont = ExpressionFunctionDefinition< @@ -101,10 +110,18 @@ export const font: ExpressionFunctionFont = { size: { default: `{ theme "font.size" default=14 }`, help: i18n.translate('expressions.functions.font.args.sizeHelpText', { - defaultMessage: 'The font size in pixels', + defaultMessage: 'The font size', }), types: ['number'], }, + sizeUnit: { + default: `px`, + help: i18n.translate('expressions.functions.font.args.sizeUnitHelpText', { + defaultMessage: 'The font size unit', + }), + types: ['string'], + options: ['px', 'pt'], + }, underline: { default: `{ theme "font.underline" default=false }`, help: i18n.translate('expressions.functions.font.args.underlineHelpText', { @@ -155,13 +172,25 @@ export const font: ExpressionFunctionFont = { // pixel setting const lineHeight = args.lHeight != null ? `${args.lHeight}px` : '1'; + const availableSizeUnits: string[] = [FontSizeUnit.PX, FontSizeUnit.PT]; + if (args.sizeUnit && !availableSizeUnits.includes(args.sizeUnit)) { + throw new Error( + i18n.translate('expressions.functions.font.invalidSizeUnitErrorMessage', { + defaultMessage: "Invalid size unit: '{sizeUnit}'", + values: { + sizeUnit: args.sizeUnit, + }, + }) + ); + } + const spec: CSSStyle = { fontFamily: args.family, fontWeight: args.weight, fontStyle: args.italic ? FontStyle.ITALIC : FontStyle.NORMAL, textDecoration: args.underline ? TextDecoration.UNDERLINE : TextDecoration.NONE, textAlign: args.align, - fontSize: `${args.size}px`, // apply font size as a pixel setting + fontSize: `${args.size}${args.sizeUnit}`, lineHeight, // apply line height as a pixel setting }; diff --git a/src/plugins/expressions/common/fonts.ts b/src/plugins/expressions/common/fonts.ts index f52282aa8f2f6..6f5c64ccea81e 100644 --- a/src/plugins/expressions/common/fonts.ts +++ b/src/plugins/expressions/common/fonts.ts @@ -92,6 +92,12 @@ export const hoeflerText = createFont({ value: "'Hoefler Text', Garamond, Georgia, 'Times New Roman', Times, serif", }); +export const inter = createFont({ + label: 'Inter', + value: + "'Inter', 'Inter UI', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'", +}); + export const lucidaGrande = createFont({ label: 'Lucida Grande', value: "'Lucida Grande', 'Lucida Sans Unicode', Lucida, Verdana, Helvetica, Arial, sans-serif", @@ -132,6 +138,7 @@ export const fonts = [ gillSans, helveticaNeue, hoeflerText, + inter, lucidaGrande, myriad, openSans, diff --git a/src/plugins/expressions/common/types/style.ts b/src/plugins/expressions/common/types/style.ts index 8c37dfa34b02a..861dcf2580d25 100644 --- a/src/plugins/expressions/common/types/style.ts +++ b/src/plugins/expressions/common/types/style.ts @@ -84,6 +84,11 @@ export enum TextDecoration { UNDERLINE = 'underline', } +export enum FontSizeUnit { + PX = 'px', + PT = 'pt', +} + /** * Represents the various style properties that can be applied to an element. */ diff --git a/src/plugins/home/public/application/components/tutorial/__snapshots__/introduction.test.js.snap b/src/plugins/home/public/application/components/tutorial/__snapshots__/introduction.test.js.snap index 39bdda213acba..247f43df76d3b 100644 --- a/src/plugins/home/public/application/components/tutorial/__snapshots__/introduction.test.js.snap +++ b/src/plugins/home/public/application/components/tutorial/__snapshots__/introduction.test.js.snap @@ -1,118 +1,198 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`props exportedFieldsUrl 1`] = ` - - +
+ + + +
+ + -
- - - + + +
+ + + +
+ + } + pageTitle={ + + Great tutorial - - } - pageTitle={ - - Great tutorial - - } -/> + } + /> + `; exports[`props iconType 1`] = ` - - +
+ + - - } - iconType="logoElastic" - pageTitle={ - - Great tutorial - - } -/> + +
+ + + + + } + iconType="logoElastic" + pageTitle={ + + Great tutorial + + } + /> + `; exports[`props isBeta 1`] = ` - - +
+ + - - } - pageTitle={ - - Great tutorial + +
+ + -   - - - } -/> + } + pageTitle={ + + Great tutorial + +   + + + + } + /> + `; exports[`props previewUrl 1`] = ` - - +
+ + - - } - pageTitle={ - - Great tutorial - - } - rightSideItems={ - Array [ - , - ] - } -/> + +
+ + + + + } + pageTitle={ + + Great tutorial + + } + rightSideItems={ + Array [ + , + ] + } + /> + `; exports[`render 1`] = ` - - +
+ + - - } - pageTitle={ - - Great tutorial - - } -/> + +
+ + + + + } + pageTitle={ + + Great tutorial + + } + /> + `; diff --git a/src/plugins/home/public/application/components/tutorial/__snapshots__/tutorial.test.js.snap b/src/plugins/home/public/application/components/tutorial/__snapshots__/tutorial.test.js.snap index 91dcdabd75dee..9dfa395d04b71 100644 --- a/src/plugins/home/public/application/components/tutorial/__snapshots__/tutorial.test.js.snap +++ b/src/plugins/home/public/application/components/tutorial/__snapshots__/tutorial.test.js.snap @@ -6,6 +6,11 @@ exports[`isCloudEnabled is false should not render instruction toggle when ON_PR >
- {title} - {betaBadge && ( - <> -   - {betaBadge} - - )} - - } - description={ - <> - - {exportedFields} - {notices} - - } - rightSideItems={rightSideItems} - /> + <> +
+ + + +
+ + + {title} + {betaBadge && ( + <> +   + {betaBadge} + + )} + + } + description={ + <> + + {exportedFields} + {notices} + + } + rightSideItems={rightSideItems} + /> + ); } diff --git a/src/plugins/home/public/application/components/tutorial/introduction.test.js b/src/plugins/home/public/application/components/tutorial/introduction.test.js index 949f84d0181ed..49293fa13b015 100644 --- a/src/plugins/home/public/application/components/tutorial/introduction.test.js +++ b/src/plugins/home/public/application/components/tutorial/introduction.test.js @@ -10,12 +10,16 @@ import React from 'react'; import { shallowWithIntl } from '@kbn/test/jest'; import { Introduction } from './introduction'; +import { httpServiceMock } from '../../../../../../core/public/mocks'; + +const basePathMock = httpServiceMock.createBasePath(); test('render', () => { const component = shallowWithIntl( ); expect(component).toMatchSnapshot(); // eslint-disable-line @@ -27,6 +31,7 @@ describe('props', () => { ); @@ -38,6 +43,7 @@ describe('props', () => { ); @@ -49,6 +55,7 @@ describe('props', () => { ); @@ -60,6 +67,7 @@ describe('props', () => { ); diff --git a/src/plugins/home/public/application/components/tutorial/tutorial.js b/src/plugins/home/public/application/components/tutorial/tutorial.js index 4af5e362baca9..fa77d46a5394f 100644 --- a/src/plugins/home/public/application/components/tutorial/tutorial.js +++ b/src/plugins/home/public/application/components/tutorial/tutorial.js @@ -421,6 +421,7 @@ class TutorialUi extends React.Component { iconType={icon} isBeta={this.state.tutorial.isBeta} notices={this.renderModuleNotices()} + basePath={getServices().http.basePath} /> {this.renderInstructionSetsToggle()} diff --git a/src/plugins/home/public/application/components/tutorial/tutorial.test.js b/src/plugins/home/public/application/components/tutorial/tutorial.test.js index c68f5ec69e161..73499c0dcb75f 100644 --- a/src/plugins/home/public/application/components/tutorial/tutorial.test.js +++ b/src/plugins/home/public/application/components/tutorial/tutorial.test.js @@ -15,6 +15,7 @@ jest.mock('../../kibana_services', () => ({ getServices: () => ({ http: { post: jest.fn().mockImplementation(async () => ({ count: 1 })), + basePath: { prepend: (path) => `/foo/${path}` }, }, getBasePath: jest.fn(() => 'path'), chrome: { diff --git a/src/plugins/index_pattern_field_editor/public/open_editor.tsx b/src/plugins/index_pattern_field_editor/public/open_editor.tsx index 19b5d1fde8315..0109b8d95db52 100644 --- a/src/plugins/index_pattern_field_editor/public/open_editor.tsx +++ b/src/plugins/index_pattern_field_editor/public/open_editor.tsx @@ -150,6 +150,9 @@ export const getFieldEditorOpener = flyout.close(); } }, + maskProps: { + className: 'indexPatternFieldEditorMaskOverlay', + }, } ); diff --git a/src/plugins/kibana_overview/public/components/overview/overview.tsx b/src/plugins/kibana_overview/public/components/overview/overview.tsx index 6a0279bd12465..5108150f7ff8d 100644 --- a/src/plugins/kibana_overview/public/components/overview/overview.tsx +++ b/src/plugins/kibana_overview/public/components/overview/overview.tsx @@ -84,6 +84,9 @@ export const Overview: FC = ({ newsFetchResult, solutions, features }) => solution: i18n.translate('kibanaOverview.noDataConfig.solutionName', { defaultMessage: `Analytics`, }), + pageTitle: i18n.translate('kibanaOverview.noDataConfig.pageTitle', { + defaultMessage: `Welcome to Analytics!`, + }), logo: 'logoKibana', actions: { elasticAgent: { diff --git a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/rollups/integration_tests/daily_rollups.test.ts b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/rollups/integration_tests/daily_rollups.test.ts index dafd4414db192..d4f069560443b 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/rollups/integration_tests/daily_rollups.test.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/rollups/integration_tests/daily_rollups.test.ts @@ -56,7 +56,8 @@ const outdatedRawEventLoopDelaysDaily = [ createRawObject(moment().subtract(7, 'days')), ]; -describe('daily rollups integration test', () => { +// FLAKY https://github.com/elastic/kibana/issues/111821 +describe.skip('daily rollups integration test', () => { let esServer: TestElasticsearchUtils; let root: TestKibanaUtils['root']; let internalRepository: ISavedObjectsRepository; diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts index d8d0215fd751f..356aaf60b423c 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts @@ -420,6 +420,10 @@ export const stackManagementSchema: MakeSchemaFrom = { type: 'integer', _meta: { description: 'Non-default value of setting.' }, }, + 'observability:enableComparisonByDefault': { + type: 'boolean', + _meta: { description: 'Non-default value of setting.' }, + }, 'banners:placement': { type: 'keyword', _meta: { description: 'Non-default value of setting.' }, @@ -440,6 +444,10 @@ export const stackManagementSchema: MakeSchemaFrom = { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, }, + 'labs:canvas:byValueEmbeddable': { + type: 'boolean', + _meta: { description: 'Non-default value of setting.' }, + }, 'labs:canvas:useDataService': { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts index 9dcd2038edb9d..69287d37dfa28 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts @@ -37,6 +37,7 @@ export interface UsageStats { 'securitySolution:rulesTableRefresh': string; 'observability:enableInspectEsQueries': boolean; 'observability:maxSuggestions': number; + 'observability:enableComparisonByDefault': boolean; 'visualize:enableLabs': boolean; 'visualization:heatmap:maxBuckets': number; 'visualization:colorMapping': string; @@ -121,6 +122,7 @@ export interface UsageStats { 'banners:textColor': string; 'banners:backgroundColor': string; 'labs:canvas:enable_ui': boolean; + 'labs:canvas:byValueEmbeddable': boolean; 'labs:canvas:useDataService': boolean; 'labs:presentation:timeToPresent': boolean; 'labs:dashboard:enable_ui': boolean; diff --git a/src/plugins/presentation_util/common/labs.ts b/src/plugins/presentation_util/common/labs.ts index cb976e73b5edf..8eefbd6981280 100644 --- a/src/plugins/presentation_util/common/labs.ts +++ b/src/plugins/presentation_util/common/labs.ts @@ -11,7 +11,9 @@ import { i18n } from '@kbn/i18n'; export const LABS_PROJECT_PREFIX = 'labs:'; export const DEFER_BELOW_FOLD = `${LABS_PROJECT_PREFIX}dashboard:deferBelowFold` as const; export const DASHBOARD_CONTROLS = `${LABS_PROJECT_PREFIX}dashboard:dashboardControls` as const; -export const projectIDs = [DEFER_BELOW_FOLD, DASHBOARD_CONTROLS] as const; +export const BY_VALUE_EMBEDDABLE = `${LABS_PROJECT_PREFIX}canvas:byValueEmbeddable` as const; + +export const projectIDs = [DEFER_BELOW_FOLD, DASHBOARD_CONTROLS, BY_VALUE_EMBEDDABLE] as const; export const environmentNames = ['kibana', 'browser', 'session'] as const; export const solutionNames = ['canvas', 'dashboard', 'presentation'] as const; @@ -48,6 +50,19 @@ export const projects: { [ID in ProjectID]: ProjectConfig & { id: ID } } = { }), solutions: ['dashboard'], }, + [BY_VALUE_EMBEDDABLE]: { + id: BY_VALUE_EMBEDDABLE, + isActive: true, + isDisplayed: true, + environments: ['kibana', 'browser', 'session'], + name: i18n.translate('presentationUtil.labs.enableByValueEmbeddableName', { + defaultMessage: 'By-Value Embeddables', + }), + description: i18n.translate('presentationUtil.labs.enableByValueEmbeddableDescription', { + defaultMessage: 'Enables support for by-value embeddables in Canvas', + }), + solutions: ['canvas'], + }, }; export type ProjectID = typeof projectIDs[number]; diff --git a/src/plugins/presentation_util/public/components/solution_toolbar/items/quick_group.scss b/src/plugins/presentation_util/public/components/solution_toolbar/items/quick_group.scss index 434f06b69a684..9f70ae353405b 100644 --- a/src/plugins/presentation_util/public/components/solution_toolbar/items/quick_group.scss +++ b/src/plugins/presentation_util/public/components/solution_toolbar/items/quick_group.scss @@ -1,9 +1,25 @@ .quickButtonGroup { - .quickButtonGroup__button { - background-color: $euiColorEmptyShade; - // sass-lint:disable-block no-important - border-width: $euiBorderWidthThin !important; - border-style: solid !important; - border-color: $euiBorderColor !important; + .euiButtonGroup__buttons { + border-radius: $euiBorderRadius; + + .quickButtonGroup__button { + background-color: $euiColorEmptyShade; + // sass-lint:disable-block no-important + border-width: $euiBorderWidthThin !important; + border-style: solid !important; + border-color: $euiBorderColor !important; + } + + .quickButtonGroup__button:first-of-type { + // sass-lint:disable-block no-important + border-top-left-radius: $euiBorderRadius !important; + border-bottom-left-radius: $euiBorderRadius !important; + } + + .quickButtonGroup__button:last-of-type { + // sass-lint:disable-block no-important + border-top-right-radius: $euiBorderRadius !important; + border-bottom-right-radius: $euiBorderRadius !important; + } } } diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index 251fed955788e..21273482dd2b8 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -7647,6 +7647,12 @@ "description": "Non-default value of setting." } }, + "observability:enableComparisonByDefault": { + "type": "boolean", + "_meta": { + "description": "Non-default value of setting." + } + }, "banners:placement": { "type": "keyword", "_meta": { @@ -7677,6 +7683,12 @@ "description": "Non-default value of setting." } }, + "labs:canvas:byValueEmbeddable": { + "type": "boolean", + "_meta": { + "description": "Non-default value of setting." + } + }, "labs:canvas:useDataService": { "type": "boolean", "_meta": { @@ -9158,4 +9170,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/plugins/vis_types/metric/public/__snapshots__/to_ast.test.ts.snap b/src/plugins/vis_types/metric/public/__snapshots__/to_ast.test.ts.snap index 46e86c4c25de1..233e38874e6da 100644 --- a/src/plugins/vis_types/metric/public/__snapshots__/to_ast.test.ts.snap +++ b/src/plugins/vis_types/metric/public/__snapshots__/to_ast.test.ts.snap @@ -34,6 +34,31 @@ Object { }, Object { "arguments": Object { + "font": Array [ + Object { + "chain": Array [ + Object { + "arguments": Object { + "align": Array [ + "center", + ], + "family": Array [ + "'Inter', 'Inter UI', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'", + ], + "sizeUnit": Array [ + "pt", + ], + "weight": Array [ + "bold", + ], + }, + "function": "font", + "type": "function", + }, + ], + "type": "expression", + }, + ], "percentageMode": Array [ true, ], @@ -83,6 +108,31 @@ Object { }, Object { "arguments": Object { + "font": Array [ + Object { + "chain": Array [ + Object { + "arguments": Object { + "align": Array [ + "center", + ], + "family": Array [ + "'Inter', 'Inter UI', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'", + ], + "sizeUnit": Array [ + "pt", + ], + "weight": Array [ + "bold", + ], + }, + "function": "font", + "type": "function", + }, + ], + "type": "expression", + }, + ], "showLabels": Array [ false, ], diff --git a/src/plugins/vis_types/metric/public/to_ast.ts b/src/plugins/vis_types/metric/public/to_ast.ts index 1e23a10dd7608..852aa70269994 100644 --- a/src/plugins/vis_types/metric/public/to_ast.ts +++ b/src/plugins/vis_types/metric/public/to_ast.ts @@ -9,11 +9,14 @@ import { get } from 'lodash'; import { getVisSchemas, SchemaConfig, VisToExpressionAst } from '../../../visualizations/public'; import { buildExpression, buildExpressionFunction } from '../../../expressions/public'; +import { inter } from '../../../expressions/common'; + import { EsaggsExpressionFunctionDefinition, IndexPatternLoadExpressionFunctionDefinition, } from '../../../data/public'; import { VisParams } from './types'; +import { getStopsWithColorsFromRanges } from './utils'; const prepareDimension = (params: SchemaConfig) => { const visdimension = buildExpressionFunction('visdimension', { accessor: params.accessor }); @@ -43,7 +46,6 @@ export const toExpressionAst: VisToExpressionAst = (vis, params) => { const { percentageMode, percentageFormatPattern, - useRanges, colorSchema, metricColorMode, colorsRange, @@ -64,26 +66,32 @@ export const toExpressionAst: VisToExpressionAst = (vis, params) => { const metricVis = buildExpressionFunction('metricVis', { percentageMode, - colorSchema, colorMode: metricColorMode, - useRanges, - invertColors, showLabels: labels?.show ?? false, }); - if (style) { - metricVis.addArgument('bgFill', style.bgFill); - metricVis.addArgument('font', buildExpression(`font size=${style.fontSize}`)); - metricVis.addArgument('subText', style.subText); - } + // Pt unit is provided to support the previous view of the metricVis at vis_types editor. + // Inter font is defined here to override the default `openSans` font, which comes from the expession. + metricVis.addArgument( + 'font', + buildExpression( + `font family="${inter.value}" + weight="bold" + align="center" + sizeUnit="pt" + ${style ? `size=${style.fontSize}` : ''}` + ) + ); - if (colorsRange) { - colorsRange.forEach((range: any) => { - metricVis.addArgument( - 'colorRange', - buildExpression(`range from=${range.from} to=${range.to}`) - ); + if (colorsRange && colorsRange.length) { + const stopsWithColors = getStopsWithColorsFromRanges(colorsRange, colorSchema, invertColors); + const palette = buildExpressionFunction('palette', { + ...stopsWithColors, + range: 'number', + continuity: 'none', }); + + metricVis.addArgument('palette', buildExpression([palette])); } if (schemas.group) { diff --git a/src/plugins/vis_types/metric/public/utils/index.ts b/src/plugins/vis_types/metric/public/utils/index.ts new file mode 100644 index 0000000000000..fb23c97d835fe --- /dev/null +++ b/src/plugins/vis_types/metric/public/utils/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 + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { getStopsWithColorsFromRanges } from './palette'; diff --git a/src/plugins/vis_types/metric/public/utils/palette.ts b/src/plugins/vis_types/metric/public/utils/palette.ts new file mode 100644 index 0000000000000..ff3a4b10a0118 --- /dev/null +++ b/src/plugins/vis_types/metric/public/utils/palette.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 + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { ColorSchemas, getHeatmapColors } from '../../../../charts/common'; +import { Range } from '../../../../expressions'; + +export interface PaletteConfig { + color: Array; + stop: number[]; +} + +const TRANSPARENT = 'rgb(0, 0, 0, 0)'; + +const getColor = ( + index: number, + elementsCount: number, + colorSchema: ColorSchemas, + invertColors: boolean = false +) => { + const divider = Math.max(elementsCount - 1, 1); + const value = invertColors ? 1 - index / divider : index / divider; + return getHeatmapColors(value, colorSchema); +}; + +export const getStopsWithColorsFromRanges = ( + ranges: Range[], + colorSchema: ColorSchemas, + invertColors: boolean = false +) => { + return ranges.reduce( + (acc, range, index, rangesArr) => { + if ((index && range.from !== rangesArr[index - 1].to) || index === 0) { + acc.color.push(TRANSPARENT); + acc.stop.push(range.from); + } + + acc.color.push(getColor(index, rangesArr.length, colorSchema, invertColors)); + acc.stop.push(range.to); + + return acc; + }, + { color: [], stop: [] } + ); +}; diff --git a/test/api_integration/apis/console/proxy_route.ts b/test/api_integration/apis/console/proxy_route.ts index d8a5f57a41a6e..a208ef405306f 100644 --- a/test/api_integration/apis/console/proxy_route.ts +++ b/test/api_integration/apis/console/proxy_route.ts @@ -12,7 +12,8 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); - describe('POST /api/console/proxy', () => { + // Failing: See https://github.com/elastic/kibana/issues/117674 + describe.skip('POST /api/console/proxy', () => { describe('system indices behavior', () => { it('returns warning header when making requests to .kibana index', async () => { return await supertest diff --git a/test/functional/page_objects/common_page.ts b/test/functional/page_objects/common_page.ts index 69fbf7e49df3c..3955e457b5ffc 100644 --- a/test/functional/page_objects/common_page.ts +++ b/test/functional/page_objects/common_page.ts @@ -279,6 +279,9 @@ export class CommonPageObject extends FtrService { this.log.debug(msg); throw new Error(msg); } + if (appName === 'discover') { + await this.browser.setLocalStorageItem('data.autocompleteFtuePopover', 'true'); + } return currentUrl; }); diff --git a/test/functional/page_objects/dashboard_page.ts b/test/functional/page_objects/dashboard_page.ts index 3d2ba53e7ba98..77ea098c76878 100644 --- a/test/functional/page_objects/dashboard_page.ts +++ b/test/functional/page_objects/dashboard_page.ts @@ -292,6 +292,15 @@ export class DashboardPageObject extends FtrService { } public async clickNewDashboard(continueEditing = false) { + const discardButtonExists = await this.testSubjects.exists('discardDashboardPromptButton'); + if (!continueEditing && discardButtonExists) { + this.log.debug('found discard button'); + await this.testSubjects.click('discardDashboardPromptButton'); + const confirmation = await this.testSubjects.exists('confirmModalTitleText'); + if (confirmation) { + await this.common.clickConfirmOnModal(); + } + } await this.listingTable.clickNewButton('createDashboardPromptButton'); if (await this.testSubjects.exists('dashboardCreateConfirm')) { if (continueEditing) { @@ -305,6 +314,15 @@ export class DashboardPageObject extends FtrService { } public async clickNewDashboardExpectWarning(continueEditing = false) { + const discardButtonExists = await this.testSubjects.exists('discardDashboardPromptButton'); + if (!continueEditing && discardButtonExists) { + this.log.debug('found discard button'); + await this.testSubjects.click('discardDashboardPromptButton'); + const confirmation = await this.testSubjects.exists('confirmModalTitleText'); + if (confirmation) { + await this.common.clickConfirmOnModal(); + } + } await this.listingTable.clickNewButton('createDashboardPromptButton'); await this.testSubjects.existOrFail('dashboardCreateConfirm'); if (continueEditing) { diff --git a/test/functional/page_objects/discover_page.ts b/test/functional/page_objects/discover_page.ts index fa7aee4e3c54c..f9328e89cd19e 100644 --- a/test/functional/page_objects/discover_page.ts +++ b/test/functional/page_objects/discover_page.ts @@ -48,7 +48,7 @@ export class DiscoverPageObject extends FtrService { await fieldSearch.clearValue(); } - public async saveSearch(searchName: string) { + public async saveSearch(searchName: string, saveAsNew?: boolean) { await this.clickSaveSearchButton(); // preventing an occasional flakiness when the saved object wasn't set and the form can't be submitted await this.retry.waitFor( @@ -59,6 +59,14 @@ export class DiscoverPageObject extends FtrService { return (await saveButton.getAttribute('disabled')) !== 'true'; } ); + + if (saveAsNew !== undefined) { + await this.retry.waitFor(`save as new switch is set`, async () => { + await this.testSubjects.setEuiSwitch('saveAsNewCheckbox', saveAsNew ? 'check' : 'uncheck'); + return (await this.testSubjects.isEuiSwitchChecked('saveAsNewCheckbox')) === saveAsNew; + }); + } + await this.testSubjects.click('confirmSaveSavedObjectButton'); await this.header.waitUntilLoadingHasFinished(); // LeeDr - this additional checking for the saved search name was an attempt diff --git a/test/interpreter_functional/screenshots/baseline/combined_test.png b/test/interpreter_functional/screenshots/baseline/combined_test.png index 9cb5e255ec99b..5b8709d8a5388 100644 Binary files a/test/interpreter_functional/screenshots/baseline/combined_test.png and b/test/interpreter_functional/screenshots/baseline/combined_test.png differ diff --git a/test/interpreter_functional/screenshots/baseline/final_screenshot_test.png b/test/interpreter_functional/screenshots/baseline/final_screenshot_test.png index 9cb5e255ec99b..87ca2668f06ea 100644 Binary files a/test/interpreter_functional/screenshots/baseline/final_screenshot_test.png and b/test/interpreter_functional/screenshots/baseline/final_screenshot_test.png differ diff --git a/test/interpreter_functional/screenshots/baseline/metric_all_data.png b/test/interpreter_functional/screenshots/baseline/metric_all_data.png index 18dca6c2c39c2..6d2b809cbd897 100644 Binary files a/test/interpreter_functional/screenshots/baseline/metric_all_data.png and b/test/interpreter_functional/screenshots/baseline/metric_all_data.png differ diff --git a/test/interpreter_functional/screenshots/baseline/metric_multi_metric_data.png b/test/interpreter_functional/screenshots/baseline/metric_multi_metric_data.png index 1e85944250156..55e320f24524f 100644 Binary files a/test/interpreter_functional/screenshots/baseline/metric_multi_metric_data.png and b/test/interpreter_functional/screenshots/baseline/metric_multi_metric_data.png differ diff --git a/test/interpreter_functional/screenshots/baseline/metric_percentage_mode.png b/test/interpreter_functional/screenshots/baseline/metric_percentage_mode.png index bcf33d9171193..55dc5a1fa76ea 100644 Binary files a/test/interpreter_functional/screenshots/baseline/metric_percentage_mode.png and b/test/interpreter_functional/screenshots/baseline/metric_percentage_mode.png differ diff --git a/test/interpreter_functional/screenshots/baseline/metric_single_metric_data.png b/test/interpreter_functional/screenshots/baseline/metric_single_metric_data.png index a82654240e374..d405646c3bc75 100644 Binary files a/test/interpreter_functional/screenshots/baseline/metric_single_metric_data.png and b/test/interpreter_functional/screenshots/baseline/metric_single_metric_data.png differ diff --git a/test/interpreter_functional/screenshots/baseline/partial_test_1.png b/test/interpreter_functional/screenshots/baseline/partial_test_1.png index 5e43b52099d15..1a1f396799851 100644 Binary files a/test/interpreter_functional/screenshots/baseline/partial_test_1.png and b/test/interpreter_functional/screenshots/baseline/partial_test_1.png differ diff --git a/test/interpreter_functional/screenshots/baseline/partial_test_2.png b/test/interpreter_functional/screenshots/baseline/partial_test_2.png index 9cb5e255ec99b..5b8709d8a5388 100644 Binary files a/test/interpreter_functional/screenshots/baseline/partial_test_2.png and b/test/interpreter_functional/screenshots/baseline/partial_test_2.png differ diff --git a/test/interpreter_functional/snapshots/baseline/combined_test3.json b/test/interpreter_functional/snapshots/baseline/combined_test3.json index 107d3fcbc5c54..8e6d59933716d 100644 --- a/test/interpreter_functional/snapshots/baseline/combined_test3.json +++ b/test/interpreter_functional/snapshots/baseline/combined_test3.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":null,"percentageMode":false,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/final_output_test.json b/test/interpreter_functional/snapshots/baseline/final_output_test.json index 107d3fcbc5c54..8e6d59933716d 100644 --- a/test/interpreter_functional/snapshots/baseline/final_output_test.json +++ b/test/interpreter_functional/snapshots/baseline/final_output_test.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":null,"percentageMode":false,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/metric_all_data.json b/test/interpreter_functional/snapshots/baseline/metric_all_data.json index 9c10b53ce8604..f176dfdb83e5c 100644 --- a/test/interpreter_functional/snapshots/baseline/metric_all_data.json +++ b/test/interpreter_functional/snapshots/baseline/metric_all_data.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":2,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":2,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":null,"percentageMode":false,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/metric_empty_data.json b/test/interpreter_functional/snapshots/baseline/metric_empty_data.json index 6fa08239f422d..f9df8409edfcb 100644 --- a/test/interpreter_functional/snapshots/baseline/metric_empty_data.json +++ b/test/interpreter_functional/snapshots/baseline/metric_empty_data.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":null,"percentageMode":false,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/metric_multi_metric_data.json b/test/interpreter_functional/snapshots/baseline/metric_multi_metric_data.json index 4410447d2bb20..ab19a031e8c71 100644 --- a/test/interpreter_functional/snapshots/baseline/metric_multi_metric_data.json +++ b/test/interpreter_functional/snapshots/baseline/metric_multi_metric_data.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":null,"percentageMode":false,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/metric_percentage_mode.json b/test/interpreter_functional/snapshots/baseline/metric_percentage_mode.json index 2abb3070c3d05..2112c5bccf507 100644 --- a/test/interpreter_functional/snapshots/baseline/metric_percentage_mode.json +++ b/test/interpreter_functional/snapshots/baseline/metric_percentage_mode.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":1000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":true,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":{"colors":["rgb(0,0,0,0)","rgb(100, 100, 100)"],"continuity":"none","gradient":false,"range":"number","rangeMax":10000,"rangeMin":0,"stops":[0,10000]},"percentageMode":true,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/metric_single_metric_data.json b/test/interpreter_functional/snapshots/baseline/metric_single_metric_data.json index cce892a2f8c6f..6bacc8f885e1b 100644 --- a/test/interpreter_functional/snapshots/baseline/metric_single_metric_data.json +++ b/test/interpreter_functional/snapshots/baseline/metric_single_metric_data.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":null,"percentageMode":false,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/partial_test_2.json b/test/interpreter_functional/snapshots/baseline/partial_test_2.json index 107d3fcbc5c54..8e6d59933716d 100644 --- a/test/interpreter_functional/snapshots/baseline/partial_test_2.json +++ b/test/interpreter_functional/snapshots/baseline/partial_test_2.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":null,"percentageMode":false,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/step_output_test3.json b/test/interpreter_functional/snapshots/baseline/step_output_test3.json index 107d3fcbc5c54..8e6d59933716d 100644 --- a/test/interpreter_functional/snapshots/baseline/step_output_test3.json +++ b/test/interpreter_functional/snapshots/baseline/step_output_test3.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":null,"percentageMode":false,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/combined_test3.json b/test/interpreter_functional/snapshots/session/combined_test3.json index 107d3fcbc5c54..8e6d59933716d 100644 --- a/test/interpreter_functional/snapshots/session/combined_test3.json +++ b/test/interpreter_functional/snapshots/session/combined_test3.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":null,"percentageMode":false,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/final_output_test.json b/test/interpreter_functional/snapshots/session/final_output_test.json index 107d3fcbc5c54..8e6d59933716d 100644 --- a/test/interpreter_functional/snapshots/session/final_output_test.json +++ b/test/interpreter_functional/snapshots/session/final_output_test.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":null,"percentageMode":false,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/metric_all_data.json b/test/interpreter_functional/snapshots/session/metric_all_data.json index 9c10b53ce8604..f176dfdb83e5c 100644 --- a/test/interpreter_functional/snapshots/session/metric_all_data.json +++ b/test/interpreter_functional/snapshots/session/metric_all_data.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":2,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":2,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":null,"percentageMode":false,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/metric_empty_data.json b/test/interpreter_functional/snapshots/session/metric_empty_data.json index 6fa08239f422d..f9df8409edfcb 100644 --- a/test/interpreter_functional/snapshots/session/metric_empty_data.json +++ b/test/interpreter_functional/snapshots/session/metric_empty_data.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":null,"percentageMode":false,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/metric_multi_metric_data.json b/test/interpreter_functional/snapshots/session/metric_multi_metric_data.json index 4410447d2bb20..ab19a031e8c71 100644 --- a/test/interpreter_functional/snapshots/session/metric_multi_metric_data.json +++ b/test/interpreter_functional/snapshots/session/metric_multi_metric_data.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":null,"percentageMode":false,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/metric_percentage_mode.json b/test/interpreter_functional/snapshots/session/metric_percentage_mode.json index 2abb3070c3d05..2112c5bccf507 100644 --- a/test/interpreter_functional/snapshots/session/metric_percentage_mode.json +++ b/test/interpreter_functional/snapshots/session/metric_percentage_mode.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":1000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":true,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":{"colors":["rgb(0,0,0,0)","rgb(100, 100, 100)"],"continuity":"none","gradient":false,"range":"number","rangeMax":10000,"rangeMin":0,"stops":[0,10000]},"percentageMode":true,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/metric_single_metric_data.json b/test/interpreter_functional/snapshots/session/metric_single_metric_data.json index cce892a2f8c6f..6bacc8f885e1b 100644 --- a/test/interpreter_functional/snapshots/session/metric_single_metric_data.json +++ b/test/interpreter_functional/snapshots/session/metric_single_metric_data.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":null,"percentageMode":false,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/partial_test_2.json b/test/interpreter_functional/snapshots/session/partial_test_2.json index 107d3fcbc5c54..8e6d59933716d 100644 --- a/test/interpreter_functional/snapshots/session/partial_test_2.json +++ b/test/interpreter_functional/snapshots/session/partial_test_2.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":null,"percentageMode":false,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/step_output_test3.json b/test/interpreter_functional/snapshots/session/step_output_test3.json index 107d3fcbc5c54..8e6d59933716d 100644 --- a/test/interpreter_functional/snapshots/session/step_output_test3.json +++ b/test/interpreter_functional/snapshots/session/step_output_test3.json @@ -1 +1 @@ -{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metricVis","type":"render","value":{"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"labels":{"show":true},"metricColorMode":"None","palette":null,"percentageMode":false,"style":{"bgColor":false,"css":"font-family:'Open Sans', Helvetica, Arial, sans-serif;font-weight:normal;font-style:normal;text-decoration:none;text-align:center;font-size:60px;line-height:1","labelColor":false,"spec":{"fontFamily":"'Open Sans', Helvetica, Arial, sans-serif","fontSize":"60px","fontStyle":"normal","fontWeight":"normal","lineHeight":"1","textAlign":"center","textDecoration":"none"},"type":"style"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/test_suites/run_pipeline/metric.ts b/test/interpreter_functional/test_suites/run_pipeline/metric.ts index 5483e09d6671b..09d0e076d9868 100644 --- a/test/interpreter_functional/test_suites/run_pipeline/metric.ts +++ b/test/interpreter_functional/test_suites/run_pipeline/metric.ts @@ -71,7 +71,8 @@ export default function ({ it('with percentageMode option', async () => { const expression = - 'metricVis metric={visdimension 0} percentageMode=true colorRange={range from=0 to=1000}'; + 'metricVis metric={visdimension 0} percentageMode=true \ + palette={palette stop=0 color="rgb(0,0,0,0)" stop=10000 color="rgb(100, 100, 100)" range="number" continuity="none"}'; await ( await expectExpression( 'metric_percentage_mode', diff --git a/x-pack/plugins/actions/server/builtin_action_types/index.ts b/x-pack/plugins/actions/server/builtin_action_types/index.ts index 9988e951ae86d..9f48a45fc4664 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/index.ts @@ -24,7 +24,6 @@ import { import { getActionType as getJiraActionType } from './jira'; import { getActionType as getResilientActionType } from './resilient'; import { getActionType as getTeamsActionType } from './teams'; -import { ENABLE_ITOM } from '../constants/connectors'; export type { ActionParamsType as EmailActionParams } from './email'; export { ActionTypeId as EmailActionTypeId } from './email'; export type { ActionParamsType as IndexActionParams } from './es_index'; @@ -72,12 +71,8 @@ export function registerBuiltInActionTypes({ actionTypeRegistry.register(getWebhookActionType({ logger, configurationUtilities })); actionTypeRegistry.register(getServiceNowITSMActionType({ logger, configurationUtilities })); actionTypeRegistry.register(getServiceNowSIRActionType({ logger, configurationUtilities })); + actionTypeRegistry.register(getServiceNowITOMActionType({ logger, configurationUtilities })); actionTypeRegistry.register(getJiraActionType({ logger, configurationUtilities })); actionTypeRegistry.register(getResilientActionType({ logger, configurationUtilities })); actionTypeRegistry.register(getTeamsActionType({ logger, configurationUtilities })); - - // TODO: Remove when ITOM is ready - if (ENABLE_ITOM) { - actionTypeRegistry.register(getServiceNowITOMActionType({ logger, configurationUtilities })); - } } diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.test.ts index 41f723bc9e2aa..26550f1732655 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.test.ts @@ -44,7 +44,7 @@ describe('config', () => { importSetTable: 'x_elas2_inc_int_elastic_incident', appScope: 'x_elas2_inc_int', table: 'em_event', - useImportAPI: true, + useImportAPI: false, commentFieldKey: 'work_notes', }); }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts index 52d2eb7662f53..ba29bcc39b25a 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts @@ -5,11 +5,6 @@ * 2.0. */ -import { - ENABLE_ITOM, - ENABLE_NEW_SN_ITSM_CONNECTOR, - ENABLE_NEW_SN_SIR_CONNECTOR, -} from '../../constants/connectors'; import { SNProductsConfig } from './types'; export const serviceNowITSMTable = 'incident'; @@ -24,21 +19,21 @@ export const snExternalServiceConfig: SNProductsConfig = { importSetTable: 'x_elas2_inc_int_elastic_incident', appScope: 'x_elas2_inc_int', table: 'incident', - useImportAPI: ENABLE_NEW_SN_ITSM_CONNECTOR, + useImportAPI: true, commentFieldKey: 'work_notes', }, '.servicenow-sir': { importSetTable: 'x_elas2_sir_int_elastic_si_incident', appScope: 'x_elas2_sir_int', table: 'sn_si_incident', - useImportAPI: ENABLE_NEW_SN_SIR_CONNECTOR, + useImportAPI: true, commentFieldKey: 'work_notes', }, '.servicenow-itom': { importSetTable: 'x_elas2_inc_int_elastic_incident', appScope: 'x_elas2_inc_int', table: 'em_event', - useImportAPI: ENABLE_ITOM, + useImportAPI: false, commentFieldKey: 'work_notes', }, }; diff --git a/x-pack/plugins/actions/server/constants/connectors.ts b/x-pack/plugins/actions/server/constants/connectors.ts deleted file mode 100644 index 94324e4d82bc2..0000000000000 --- a/x-pack/plugins/actions/server/constants/connectors.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -// TODO: Remove when Elastic for ITSM is published. -export const ENABLE_NEW_SN_ITSM_CONNECTOR = true; - -// TODO: Remove when Elastic for Security Operations is published. -export const ENABLE_NEW_SN_SIR_CONNECTOR = true; - -// TODO: Remove when ready -export const ENABLE_ITOM = true; diff --git a/x-pack/plugins/apm/dev_docs/query_debugging_in_development_and_production.md b/x-pack/plugins/apm/dev_docs/query_debugging_in_development_and_production.md new file mode 100644 index 0000000000000..0dcf20d3e2fed --- /dev/null +++ b/x-pack/plugins/apm/dev_docs/query_debugging_in_development_and_production.md @@ -0,0 +1,17 @@ +# Query Debugging + +When debugging an issue with the APM UI it can be very helpful to see the exact Elasticsearch queries and responses that was made for a given API request. +To enable debugging of Elasticsearch queries in APM UI do the following: + +1. Go to "Stack Management" +2. Under "Kibana" on the left-hand side, select "Advanced Settings" +3. Search for "Observability" +4. Enable "Inspect ES queries" setting +5. Click "Save" + +When you navigate back to APM UI you can now inspect Elasticsearch queries by opening your browser's Developer Tools and selecting an api request to APM's api. +There will be an `_inspect` key containing every Elasticsearch query made during that request including both requests and responses to and from Elasticsearch. + +![image](https://user-images.githubusercontent.com/209966/140500012-b075adf0-8401-40fd-99f8-85b68711de17.png) + + diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts new file mode 100644 index 0000000000000..fd6890d3a7bed --- /dev/null +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts @@ -0,0 +1,110 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import url from 'url'; +import { synthtrace } from '../../../../synthtrace'; +import { generateData } from './generate_data'; + +const start = '2021-10-10T00:00:00.000Z'; +const end = '2021-10-10T00:15:00.000Z'; + +const javaServiceErrorsPageHref = url.format({ + pathname: '/app/apm/services/opbeans-java/errors', + query: { rangeFrom: start, rangeTo: end }, +}); + +const nodeServiceErrorsPageHref = url.format({ + pathname: '/app/apm/services/opbeans-node/errors', + query: { rangeFrom: start, rangeTo: end }, +}); + +describe('Errors page', () => { + beforeEach(() => { + cy.loginAsReadOnlyUser(); + }); + + describe('when data is loaded', () => { + before(async () => { + await synthtrace.index( + generateData({ + from: new Date(start).getTime(), + to: new Date(end).getTime(), + }) + ); + }); + + after(async () => { + await synthtrace.clean(); + }); + + describe('when service has no errors', () => { + it('shows empty message', () => { + cy.visit(nodeServiceErrorsPageHref); + cy.contains('opbeans-node'); + cy.contains('No errors found'); + }); + }); + + describe('when service has errors', () => { + it('shows errors distribution chart', () => { + cy.visit(javaServiceErrorsPageHref); + cy.contains('Error occurrences'); + }); + + it('shows failed transaction rate chart', () => { + cy.visit(javaServiceErrorsPageHref); + cy.contains('Failed transaction rate'); + }); + + it('errors table is populated', () => { + cy.visit(javaServiceErrorsPageHref); + cy.contains('Error 0'); + }); + + it('clicking on an error in the list navigates to error detail page', () => { + cy.visit(javaServiceErrorsPageHref); + cy.contains('a', 'Error 1').click(); + cy.contains('div', 'Error 1'); + }); + + it('clicking on type adds a filter in the kuerybar', () => { + cy.visit(javaServiceErrorsPageHref); + cy.get('[data-test-subj="headerFilterKuerybar"]') + .invoke('val') + .should('be.empty'); + // `force: true` because Cypress says the element is 0x0 + cy.contains('exception 0').click({ + force: true, + }); + cy.get('[data-test-subj="headerFilterKuerybar"]') + .its('length') + .should('be.gt', 0); + cy.get('table') + .find('td:contains("exception 0")') + .should('have.length', 1); + }); + + it('sorts by ocurrences', () => { + cy.visit(javaServiceErrorsPageHref); + cy.contains('span', 'Occurrences').click(); + cy.url().should( + 'include', + '&sortField=occurrenceCount&sortDirection=asc' + ); + }); + + it('sorts by latest occurrences', () => { + cy.visit(javaServiceErrorsPageHref); + cy.contains('span', 'Latest occurrence').click(); + cy.url().should( + 'include', + '&sortField=latestOccurrenceAt&sortDirection=asc' + ); + }); + }); + }); +}); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/generate_data.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/generate_data.ts new file mode 100644 index 0000000000000..7f1c14ac25513 --- /dev/null +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/generate_data.ts @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { service, timerange } from '@elastic/apm-synthtrace'; + +export function generateData({ from, to }: { from: number; to: number }) { + const range = timerange(from, to); + + const opbeansJava = service('opbeans-java', 'production', 'java') + .instance('opbeans-java-prod-1') + .podId('opbeans-java-prod-1-pod'); + + const opbeansNode = service('opbeans-node', 'production', 'nodejs').instance( + 'opbeans-node-prod-1' + ); + + return [ + ...range + .interval('2m') + .rate(1) + .flatMap((timestamp, index) => [ + ...opbeansJava + .transaction('GET /apple 🍎 ') + .timestamp(timestamp) + .duration(1000) + .success() + .errors( + opbeansJava + .error(`Error ${index}`, `exception ${index}`) + .timestamp(timestamp) + ) + .serialize(), + ...opbeansNode + .transaction('GET /banana 🍌') + .timestamp(timestamp) + .duration(500) + .success() + .serialize(), + ]), + ]; +} diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/errors_table.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/errors_table.spec.ts new file mode 100644 index 0000000000000..9ea6ef028b805 --- /dev/null +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/errors_table.spec.ts @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import url from 'url'; +import { synthtrace } from '../../../../synthtrace'; +import { opbeans } from '../../../fixtures/synthtrace/opbeans'; + +const start = '2021-10-10T00:00:00.000Z'; +const end = '2021-10-10T00:15:00.000Z'; + +const serviceOverviewHref = url.format({ + pathname: '/app/apm/services/opbeans-java/overview', + query: { rangeFrom: start, rangeTo: end }, +}); + +describe('Errors table', () => { + before(async () => { + await synthtrace.index( + opbeans({ + from: new Date(start).getTime(), + to: new Date(end).getTime(), + }) + ); + }); + + after(async () => { + await synthtrace.clean(); + }); + + beforeEach(() => { + cy.loginAsReadOnlyUser(); + }); + + it('errors table is populated', () => { + cy.visit(serviceOverviewHref); + cy.contains('opbeans-java'); + cy.contains('[MockError] Foo'); + }); + + it('navigates to the errors page', () => { + cy.visit(serviceOverviewHref); + cy.contains('opbeans-java'); + cy.contains('a', 'View errors').click(); + cy.url().should('include', '/opbeans-java/errors'); + }); + + it('navigates to error detail page', () => { + cy.visit(serviceOverviewHref); + cy.contains('a', '[MockError] Foo').click(); + cy.contains('div', 'Exception message'); + }); +}); diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_throughput_chart.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_throughput_chart.tsx index 058c7d97b43cc..7472eb780f119 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_throughput_chart.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_throughput_chart.tsx @@ -30,7 +30,6 @@ import { const INITIAL_STATE = { currentPeriod: [], previousPeriod: [], - throughputUnit: 'minute' as const, }; export function ServiceOverviewThroughputChart({ diff --git a/x-pack/plugins/apm/public/components/routing/home/index.tsx b/x-pack/plugins/apm/public/components/routing/home/index.tsx index 025fa8ddcc8a0..25a68592d2b11 100644 --- a/x-pack/plugins/apm/public/components/routing/home/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/home/index.tsx @@ -69,6 +69,8 @@ export const home = { t.partial({ refreshPaused: t.union([t.literal('true'), t.literal('false')]), refreshInterval: t.string, + comparisonEnabled: toBooleanRt, + comparisonType: comparisonTypeRt, }), ]), }), diff --git a/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx b/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx index 4afa10cbf9a5d..37259f7c91e22 100644 --- a/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx @@ -135,6 +135,8 @@ export const serviceDetail = { t.partial({ traceId: t.string, transactionId: t.string, + comparisonEnabled: toBooleanRt, + comparisonType: comparisonTypeRt, }), ]), }), diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_detail_link.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_detail_link.tsx index 8b885526fb67c..3de16cf4db029 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_detail_link.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_detail_link.tsx @@ -14,6 +14,7 @@ import { useLegacyUrlParams } from '../../../../context/url_params_context/use_u import { pickKeys } from '../../../../../common/utils/pick_keys'; import { APMQueryParams } from '../url_helpers'; import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context'; +import { TimeRangeComparisonType } from '../../../../../common/runtime_types/comparison_type_rt'; interface Props extends APMLinkExtendProps { serviceName: string; @@ -23,6 +24,8 @@ interface Props extends APMLinkExtendProps { transactionType: string; latencyAggregationType?: string; environment?: string; + comparisonEnabled?: boolean; + comparisonType?: TimeRangeComparisonType; } const persistedFilters: Array = [ @@ -38,6 +41,8 @@ export function TransactionDetailLink({ transactionType, latencyAggregationType, environment, + comparisonEnabled, + comparisonType, ...rest }: Props) { const { urlParams } = useLegacyUrlParams(); @@ -51,6 +56,8 @@ export function TransactionDetailLink({ transactionId, transactionName, transactionType, + comparisonEnabled, + comparisonType, ...pickKeys(urlParams as APMQueryParams, ...persistedFilters), ...pickBy({ latencyAggregationType, environment }, identity), }, diff --git a/x-pack/plugins/apm/public/components/shared/time_comparison/get_comparison_enabled.test.ts b/x-pack/plugins/apm/public/components/shared/time_comparison/get_comparison_enabled.test.ts new file mode 100644 index 0000000000000..23e1c94729204 --- /dev/null +++ b/x-pack/plugins/apm/public/components/shared/time_comparison/get_comparison_enabled.test.ts @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { CoreStart } from 'kibana/public'; +import { getComparisonEnabled } from './get_comparison_enabled'; + +describe('getComparisonEnabled', () => { + function mockValues({ + uiSettings, + urlComparisonEnabled, + }: { + uiSettings: boolean; + urlComparisonEnabled?: boolean; + }) { + return { + core: { uiSettings: { get: () => uiSettings } } as unknown as CoreStart, + urlComparisonEnabled, + }; + } + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('returns false when kibana config is disabled and url is empty', () => { + const { core, urlComparisonEnabled } = mockValues({ + uiSettings: false, + urlComparisonEnabled: undefined, + }); + expect(getComparisonEnabled({ core, urlComparisonEnabled })).toBeFalsy(); + }); + + it('returns true when kibana config is enabled and url is empty', () => { + const { core, urlComparisonEnabled } = mockValues({ + uiSettings: true, + urlComparisonEnabled: undefined, + }); + expect(getComparisonEnabled({ core, urlComparisonEnabled })).toBeTruthy(); + }); + + it('returns true when defined as true in the url', () => { + const { core, urlComparisonEnabled } = mockValues({ + uiSettings: false, + urlComparisonEnabled: true, + }); + expect(getComparisonEnabled({ core, urlComparisonEnabled })).toBeTruthy(); + }); + + it('returns false when defined as false in the url', () => { + const { core, urlComparisonEnabled } = mockValues({ + uiSettings: true, + urlComparisonEnabled: false, + }); + expect(getComparisonEnabled({ core, urlComparisonEnabled })).toBeFalsy(); + }); +}); diff --git a/x-pack/plugins/apm/public/components/shared/time_comparison/get_comparison_enabled.ts b/x-pack/plugins/apm/public/components/shared/time_comparison/get_comparison_enabled.ts new file mode 100644 index 0000000000000..5f2ca5dca4656 --- /dev/null +++ b/x-pack/plugins/apm/public/components/shared/time_comparison/get_comparison_enabled.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { CoreStart } from 'kibana/public'; +import { enableComparisonByDefault } from '../../../../../observability/public'; + +export function getComparisonEnabled({ + core, + urlComparisonEnabled, +}: { + core: CoreStart; + urlComparisonEnabled?: boolean; +}) { + const isEnabledByDefault = core.uiSettings.get( + enableComparisonByDefault + ); + + return urlComparisonEnabled ?? isEnabledByDefault; +} diff --git a/x-pack/plugins/apm/public/components/shared/time_comparison/index.tsx b/x-pack/plugins/apm/public/components/shared/time_comparison/index.tsx index 9d077713ff12e..db085861ae095 100644 --- a/x-pack/plugins/apm/public/components/shared/time_comparison/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/time_comparison/index.tsx @@ -14,10 +14,12 @@ import { euiStyled } from '../../../../../../../src/plugins/kibana_react/common' import { useUiTracker } from '../../../../../observability/public'; import { TimeRangeComparisonEnum } from '../../../../common/runtime_types/comparison_type_rt'; import { useLegacyUrlParams } from '../../../context/url_params_context/use_url_params'; +import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context'; import { useApmParams } from '../../../hooks/use_apm_params'; import { useBreakpoints } from '../../../hooks/use_breakpoints'; import { useTimeRange } from '../../../hooks/use_time_range'; import * as urlHelpers from '../../shared/Links/url_helpers'; +import { getComparisonEnabled } from './get_comparison_enabled'; import { getComparisonTypes } from './get_comparison_types'; import { getTimeRangeComparison } from './get_time_range_comparison'; @@ -113,6 +115,7 @@ export function getSelectOptions({ } export function TimeComparison() { + const { core } = useApmPluginContext(); const trackApmEvent = useUiTracker({ app: 'apm' }); const history = useHistory(); const { isSmall } = useBreakpoints(); @@ -138,7 +141,13 @@ export function TimeComparison() { if (comparisonEnabled === undefined || comparisonType === undefined) { urlHelpers.replace(history, { query: { - comparisonEnabled: comparisonEnabled === false ? 'false' : 'true', + comparisonEnabled: + getComparisonEnabled({ + core, + urlComparisonEnabled: comparisonEnabled, + }) === false + ? 'false' + : 'true', comparisonType: comparisonType ? comparisonType : comparisonTypes[0], }, }); diff --git a/x-pack/plugins/apm/public/components/shared/transactions_table/get_columns.tsx b/x-pack/plugins/apm/public/components/shared/transactions_table/get_columns.tsx index 18e9beb2c8795..c44fbb8b7f87a 100644 --- a/x-pack/plugins/apm/public/components/shared/transactions_table/get_columns.tsx +++ b/x-pack/plugins/apm/public/components/shared/transactions_table/get_columns.tsx @@ -15,6 +15,7 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import { ValuesType } from 'utility-types'; import { LatencyAggregationType } from '../../../../common/latency_aggregation_types'; +import { TimeRangeComparisonType } from '../../../../common/runtime_types/comparison_type_rt'; import { asMillisecondDuration, asPercent, @@ -42,12 +43,14 @@ export function getColumns({ transactionGroupDetailedStatistics, comparisonEnabled, shouldShowSparkPlots = true, + comparisonType, }: { serviceName: string; latencyAggregationType?: LatencyAggregationType; transactionGroupDetailedStatistics?: TransactionGroupDetailedStatistics; comparisonEnabled?: boolean; shouldShowSparkPlots?: boolean; + comparisonType?: TimeRangeComparisonType; }): Array> { return [ { @@ -67,6 +70,8 @@ export function getColumns({ transactionName={name} transactionType={type} latencyAggregationType={latencyAggregationType} + comparisonEnabled={comparisonEnabled} + comparisonType={comparisonType} > {name} diff --git a/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx b/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx index 6c934cc51e2f7..2d9f6584535fa 100644 --- a/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx @@ -222,6 +222,7 @@ export function TransactionsTable({ transactionGroupDetailedStatistics, comparisonEnabled, shouldShowSparkPlots, + comparisonType, }); const isLoading = status === FETCH_STATUS.LOADING; diff --git a/x-pack/plugins/apm/readme.md b/x-pack/plugins/apm/readme.md index 040e620ae91ca..df7b641fbb231 100644 --- a/x-pack/plugins/apm/readme.md +++ b/x-pack/plugins/apm/readme.md @@ -13,6 +13,9 @@ ## Tooling - [VSCode setup instructions](./dev_docs/vscode_setup.md) - [Github PR commands](./dev_docs/github_commands.md) +- [Synthtrace (data generation)](https://github.com/elastic/kibana/blob/main/packages/elastic-apm-synthtrace/README.md) +- [Query debugging in development and production](./dev_docs/query_debugging_in_development_and_production.md) ## Other resources - [Official APM UI settings docs](https://www.elastic.co/guide/en/kibana/current/apm-settings-in-kibana.html) +- [Reading Material](./dev_docs/learning_material.md) diff --git a/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_duration.ts b/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_duration.ts index 8767b5a60d9b2..693502d7629e8 100644 --- a/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_duration.ts +++ b/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_duration.ts @@ -6,7 +6,7 @@ */ import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { rangeQuery } from '../../../../../observability/server'; +import { rangeQuery, termQuery } from '../../../../../observability/server'; import { SERVICE_NAME, TRANSACTION_TYPE, @@ -46,10 +46,8 @@ export async function getTransactionDurationChartPreview({ const query = { bool: { filter: [ - ...(serviceName ? [{ term: { [SERVICE_NAME]: serviceName } }] : []), - ...(transactionType - ? [{ term: { [TRANSACTION_TYPE]: transactionType } }] - : []), + ...termQuery(SERVICE_NAME, serviceName), + ...termQuery(TRANSACTION_TYPE, transactionType), ...rangeQuery(start, end), ...environmentQuery(environment), ...getDocumentTypeFilterForTransactions(searchAggregatedTransactions), diff --git a/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_error_count.ts b/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_error_count.ts index 0cd1c1cddc651..0e1fa74199f60 100644 --- a/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_error_count.ts +++ b/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_error_count.ts @@ -8,7 +8,7 @@ import { SERVICE_NAME } from '../../../../common/elasticsearch_fieldnames'; import { ProcessorEvent } from '../../../../common/processor_event'; import { AlertParams } from '../../../routes/alerts/chart_preview'; -import { rangeQuery } from '../../../../../observability/server'; +import { rangeQuery, termQuery } from '../../../../../observability/server'; import { environmentQuery } from '../../../../common/utils/environment_query'; import { Setup } from '../../helpers/setup_request'; @@ -25,7 +25,7 @@ export async function getTransactionErrorCountChartPreview({ const query = { bool: { filter: [ - ...(serviceName ? [{ term: { [SERVICE_NAME]: serviceName } }] : []), + ...termQuery(SERVICE_NAME, serviceName), ...rangeQuery(start, end), ...environmentQuery(environment), ], diff --git a/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_error_rate.ts b/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_error_rate.ts index d3f03c597e8fb..e2bfaf29f83cb 100644 --- a/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_error_rate.ts +++ b/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_error_rate.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { rangeQuery } from '../../../../../observability/server'; +import { rangeQuery, termQuery } from '../../../../../observability/server'; import { SERVICE_NAME, TRANSACTION_TYPE, @@ -52,10 +52,8 @@ export async function getTransactionErrorRateChartPreview({ query: { bool: { filter: [ - ...(serviceName ? [{ term: { [SERVICE_NAME]: serviceName } }] : []), - ...(transactionType - ? [{ term: { [TRANSACTION_TYPE]: transactionType } }] - : []), + ...termQuery(SERVICE_NAME, serviceName), + ...termQuery(TRANSACTION_TYPE, transactionType), ...rangeQuery(start, end), ...environmentQuery(environment), ...getDocumentTypeFilterForTransactions( diff --git a/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts index 7fe2adcfe24d7..17beacae4b14d 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts @@ -41,6 +41,7 @@ import { getApmIndices } from '../settings/apm_indices/get_apm_indices'; import { apmActionVariables } from './action_variables'; import { alertingEsClient } from './alerting_es_client'; import { RegisterRuleDependencies } from './register_apm_alerts'; +import { termQuery } from '../../../../observability/server'; const ALERT_EVALUATION_THRESHOLD: typeof ALERT_EVALUATION_THRESHOLD_TYPED = ALERT_EVALUATION_THRESHOLD_NON_TYPED; @@ -113,9 +114,7 @@ export function registerErrorCountAlertType({ }, }, { term: { [PROCESSOR_EVENT]: ProcessorEvent.error } }, - ...(alertParams.serviceName - ? [{ term: { [SERVICE_NAME]: alertParams.serviceName } }] - : []), + ...termQuery(SERVICE_NAME, alertParams.serviceName), ...environmentQuery(alertParams.environment), ], }, diff --git a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_anomaly_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_anomaly_alert_type.ts index 2809d7feadb37..ec2fbb4028b74 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_anomaly_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_anomaly_alert_type.ts @@ -46,6 +46,7 @@ import { getEnvironmentEsField, getEnvironmentLabel, } from '../../../common/environment_filter_values'; +import { termQuery } from '../../../../observability/server'; const ALERT_EVALUATION_THRESHOLD: typeof ALERT_EVALUATION_THRESHOLD_TYPED = ALERT_EVALUATION_THRESHOLD_NON_TYPED; @@ -157,24 +158,11 @@ export function registerTransactionDurationAnomalyAlertType({ }, }, }, - ...(alertParams.serviceName - ? [ - { - term: { - partition_field_value: alertParams.serviceName, - }, - }, - ] - : []), - ...(alertParams.transactionType - ? [ - { - term: { - by_field_value: alertParams.transactionType, - }, - }, - ] - : []), + ...termQuery( + 'partition_field_value', + alertParams.serviceName + ), + ...termQuery('by_field_value', alertParams.transactionType), ] as QueryDslQueryContainer[], }, }, diff --git a/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts index 5ba7ed5321d70..43dfbaf156f6c 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts @@ -48,6 +48,7 @@ import { RegisterRuleDependencies } from './register_apm_alerts'; import { SearchAggregatedTransactionSetting } from '../../../common/aggregated_transactions'; import { getDocumentTypeFilterForTransactions } from '../helpers/transactions'; import { asPercent } from '../../../../observability/common/utils/formatters'; +import { termQuery } from '../../../../observability/server'; const ALERT_EVALUATION_THRESHOLD: typeof ALERT_EVALUATION_THRESHOLD_TYPED = ALERT_EVALUATION_THRESHOLD_NON_TYPED; @@ -142,18 +143,8 @@ export function registerTransactionErrorRateAlertType({ ], }, }, - ...(alertParams.serviceName - ? [{ term: { [SERVICE_NAME]: alertParams.serviceName } }] - : []), - ...(alertParams.transactionType - ? [ - { - term: { - [TRANSACTION_TYPE]: alertParams.transactionType, - }, - }, - ] - : []), + ...termQuery(SERVICE_NAME, alertParams.serviceName), + ...termQuery(TRANSACTION_TYPE, alertParams.transactionType), ...environmentQuery(alertParams.environment), ], }, diff --git a/x-pack/plugins/apm/server/lib/backends/get_throughput_charts_for_backend.ts b/x-pack/plugins/apm/server/lib/backends/get_throughput_charts_for_backend.ts index 1fbdd1c680c58..5a7e06683f25a 100644 --- a/x-pack/plugins/apm/server/lib/backends/get_throughput_charts_for_backend.ts +++ b/x-pack/plugins/apm/server/lib/backends/get_throughput_charts_for_backend.ts @@ -15,7 +15,6 @@ import { ProcessorEvent } from '../../../common/processor_event'; import { Setup } from '../helpers/setup_request'; import { getOffsetInMs } from '../../../common/utils/get_offset_in_ms'; import { getBucketSize } from '../helpers/get_bucket_size'; -import { calculateThroughputWithInterval } from '../helpers/calculate_throughput'; export async function getThroughputChartsForBackend({ backendName, @@ -42,7 +41,7 @@ export async function getThroughputChartsForBackend({ offset, }); - const { intervalString, bucketSize } = getBucketSize({ + const { intervalString } = getBucketSize({ start: startWithOffset, end: endWithOffset, minBucketSize: 60, @@ -73,9 +72,10 @@ export async function getThroughputChartsForBackend({ extended_bounds: { min: startWithOffset, max: endWithOffset }, }, aggs: { - spanDestinationLatencySum: { - sum: { + throughput: { + rate: { field: SPAN_DESTINATION_SERVICE_RESPONSE_TIME_COUNT, + unit: 'minute', }, }, }, @@ -88,10 +88,7 @@ export async function getThroughputChartsForBackend({ response.aggregations?.timeseries.buckets.map((bucket) => { return { x: bucket.key + offsetInMs, - y: calculateThroughputWithInterval({ - bucketSize, - value: bucket.spanDestinationLatencySum.value || 0, - }), + y: bucket.throughput.value, }; }) ?? [] ); diff --git a/x-pack/plugins/apm/server/lib/environments/get_all_environments.ts b/x-pack/plugins/apm/server/lib/environments/get_all_environments.ts index d6c53aeea078e..7bdb21b9fda78 100644 --- a/x-pack/plugins/apm/server/lib/environments/get_all_environments.ts +++ b/x-pack/plugins/apm/server/lib/environments/get_all_environments.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { termQuery } from '../../../../observability/server'; import { ProcessorEvent } from '../../../common/processor_event'; import { Setup } from '../helpers/setup_request'; import { @@ -37,11 +38,6 @@ export async function getAllEnvironments({ const { apmEventClient } = setup; - // omit filter for service.name if "All" option is selected - const serviceNameFilter = serviceName - ? [{ term: { [SERVICE_NAME]: serviceName } }] - : []; - const params = { apm: { events: [ @@ -57,7 +53,7 @@ export async function getAllEnvironments({ size: 0, query: { bool: { - filter: [...serviceNameFilter], + filter: [...termQuery(SERVICE_NAME, serviceName)], }, }, aggs: { diff --git a/x-pack/plugins/apm/server/lib/environments/get_environments.ts b/x-pack/plugins/apm/server/lib/environments/get_environments.ts index 678cfd891ae57..cd5caab6d2587 100644 --- a/x-pack/plugins/apm/server/lib/environments/get_environments.ts +++ b/x-pack/plugins/apm/server/lib/environments/get_environments.ts @@ -11,7 +11,7 @@ import { } from '../../../common/elasticsearch_fieldnames'; import { ENVIRONMENT_NOT_DEFINED } from '../../../common/environment_filter_values'; import { ProcessorEvent } from '../../../common/processor_event'; -import { rangeQuery } from '../../../../observability/server'; +import { rangeQuery, termQuery } from '../../../../observability/server'; import { getProcessorEventForTransactions } from '../helpers/transactions'; import { Setup } from '../helpers/setup_request'; @@ -40,14 +40,6 @@ export async function getEnvironments({ const { apmEventClient } = setup; - const filter = rangeQuery(start, end); - - if (serviceName) { - filter.push({ - term: { [SERVICE_NAME]: serviceName }, - }); - } - const params = { apm: { events: [ @@ -60,7 +52,10 @@ export async function getEnvironments({ size: 0, query: { bool: { - filter, + filter: [ + ...rangeQuery(start, end), + ...termQuery(SERVICE_NAME, serviceName), + ], }, }, aggs: { diff --git a/x-pack/plugins/apm/server/lib/errors/distribution/get_buckets.ts b/x-pack/plugins/apm/server/lib/errors/distribution/get_buckets.ts index dce8a3f397eaa..625089e99d360 100644 --- a/x-pack/plugins/apm/server/lib/errors/distribution/get_buckets.ts +++ b/x-pack/plugins/apm/server/lib/errors/distribution/get_buckets.ts @@ -5,13 +5,16 @@ * 2.0. */ -import { ESFilter } from '../../../../../../../src/core/types/elasticsearch'; import { ERROR_GROUP_ID, SERVICE_NAME, } from '../../../../common/elasticsearch_fieldnames'; import { ProcessorEvent } from '../../../../common/processor_event'; -import { rangeQuery, kqlQuery } from '../../../../../observability/server'; +import { + rangeQuery, + kqlQuery, + termQuery, +} from '../../../../../observability/server'; import { environmentQuery } from '../../../../common/utils/environment_query'; import { Setup } from '../../helpers/setup_request'; @@ -35,16 +38,6 @@ export async function getBuckets({ end: number; }) { const { apmEventClient } = setup; - const filter: ESFilter[] = [ - { term: { [SERVICE_NAME]: serviceName } }, - ...rangeQuery(start, end), - ...environmentQuery(environment), - ...kqlQuery(kuery), - ]; - - if (groupId) { - filter.push({ term: { [ERROR_GROUP_ID]: groupId } }); - } const params = { apm: { @@ -54,7 +47,13 @@ export async function getBuckets({ size: 0, query: { bool: { - filter, + filter: [ + { term: { [SERVICE_NAME]: serviceName } }, + ...rangeQuery(start, end), + ...environmentQuery(environment), + ...kqlQuery(kuery), + ...termQuery(ERROR_GROUP_ID, groupId), + ], }, }, aggs: { diff --git a/x-pack/plugins/apm/server/lib/metrics/transform_metrics_chart.ts b/x-pack/plugins/apm/server/lib/metrics/transform_metrics_chart.ts index 7eaa90845d652..f4829f2d5faa0 100644 --- a/x-pack/plugins/apm/server/lib/metrics/transform_metrics_chart.ts +++ b/x-pack/plugins/apm/server/lib/metrics/transform_metrics_chart.ts @@ -26,26 +26,30 @@ export function transformDataToMetricsChart( title: chartBase.title, key: chartBase.key, yUnit: chartBase.yUnit, - series: Object.keys(chartBase.series).map((seriesKey, i) => { - const overallValue = aggregations?.[seriesKey]?.value; + series: + result.hits.total.value > 0 + ? Object.keys(chartBase.series).map((seriesKey, i) => { + const overallValue = aggregations?.[seriesKey]?.value; - return { - title: chartBase.series[seriesKey].title, - key: seriesKey, - type: chartBase.type, - color: - chartBase.series[seriesKey].color || getVizColorForIndex(i, theme), - overallValue, - data: - timeseriesData?.buckets.map((bucket) => { - const { value } = bucket[seriesKey]; - const y = value === null || isNaN(value) ? null : value; return { - x: bucket.key, - y, + title: chartBase.series[seriesKey].title, + key: seriesKey, + type: chartBase.type, + color: + chartBase.series[seriesKey].color || + getVizColorForIndex(i, theme), + overallValue, + data: + timeseriesData?.buckets.map((bucket) => { + const { value } = bucket[seriesKey]; + const y = value === null || isNaN(value) ? null : value; + return { + x: bucket.key, + y, + }; + }) || [], }; - }) || [], - }; - }), + }) + : [], }; } diff --git a/x-pack/plugins/apm/server/lib/observability_overview/get_transactions_per_minute.ts b/x-pack/plugins/apm/server/lib/observability_overview/get_transactions_per_minute.ts index 829afa8330164..de4d6dec4e1fe 100644 --- a/x-pack/plugins/apm/server/lib/observability_overview/get_transactions_per_minute.ts +++ b/x-pack/plugins/apm/server/lib/observability_overview/get_transactions_per_minute.ts @@ -16,10 +16,7 @@ import { getDocumentTypeFilterForTransactions, getProcessorEventForTransactions, } from '../helpers/transactions'; -import { - calculateThroughputWithInterval, - calculateThroughputWithRange, -} from '../helpers/calculate_throughput'; +import { calculateThroughputWithRange } from '../helpers/calculate_throughput'; export async function getTransactionsPerMinute({ setup, @@ -70,6 +67,9 @@ export async function getTransactionsPerMinute({ fixed_interval: intervalString, min_doc_count: 0, }, + aggs: { + throughput: { rate: { unit: 'minute' as const } }, + }, }, }, }, @@ -98,10 +98,7 @@ export async function getTransactionsPerMinute({ timeseries: topTransactionTypeBucket?.timeseries.buckets.map((bucket) => ({ x: bucket.key, - y: calculateThroughputWithInterval({ - bucketSize, - value: bucket.doc_count, - }), + y: bucket.throughput.value, })) || [], }; } diff --git a/x-pack/plugins/apm/server/lib/service_map/get_service_map.ts b/x-pack/plugins/apm/server/lib/service_map/get_service_map.ts index ae511d0fed8f8..aaf55413d9774 100644 --- a/x-pack/plugins/apm/server/lib/service_map/get_service_map.ts +++ b/x-pack/plugins/apm/server/lib/service_map/get_service_map.ts @@ -7,14 +7,14 @@ import { Logger } from 'kibana/server'; import { chunk } from 'lodash'; +import { ProcessorEvent } from '../../../common/processor_event'; +import { rangeQuery, termQuery } from '../../../../observability/server'; import { PromiseReturnType } from '../../../../observability/typings/common'; import { AGENT_NAME, SERVICE_ENVIRONMENT, SERVICE_NAME, } from '../../../common/elasticsearch_fieldnames'; -import { getServicesProjection } from '../../projections/services'; -import { mergeProjection } from '../../projections/util/merge_projection'; import { environmentQuery } from '../../../common/utils/environment_query'; import { withApmSpan } from '../../utils/with_apm_span'; import { Setup } from '../helpers/setup_request'; @@ -26,6 +26,7 @@ import { getServiceMapFromTraceIds } from './get_service_map_from_trace_ids'; import { getTraceSampleIds } from './get_trace_sample_ids'; import { transformServiceMapResponses } from './transform_service_map_responses'; import { ENVIRONMENT_ALL } from '../../../common/environment_filter_values'; +import { getProcessorEventForTransactions } from '../helpers/transactions'; export interface IEnvOptions { setup: Setup; @@ -94,40 +95,29 @@ async function getServicesData(options: IEnvOptions) { const { environment, setup, searchAggregatedTransactions, start, end } = options; - const projection = getServicesProjection({ - setup, - searchAggregatedTransactions, - kuery: '', - start, - end, - }); - - let filter = [ - ...projection.body.query.bool.filter, - ...environmentQuery(environment), - ]; - - if (options.serviceName) { - filter = filter.concat({ - term: { - [SERVICE_NAME]: options.serviceName, - }, - }); - } - - const params = mergeProjection(projection, { + const params = { + apm: { + events: [ + getProcessorEventForTransactions(searchAggregatedTransactions), + ProcessorEvent.metric as const, + ProcessorEvent.error as const, + ], + }, body: { size: 0, query: { bool: { - ...projection.body.query.bool, - filter, + filter: [ + ...rangeQuery(start, end), + ...environmentQuery(environment), + ...termQuery(SERVICE_NAME, options.serviceName), + ], }, }, aggs: { services: { terms: { - field: projection.body.aggs.services.terms.field, + field: SERVICE_NAME, size: 500, }, aggs: { @@ -140,7 +130,7 @@ async function getServicesData(options: IEnvOptions) { }, }, }, - }); + }; const { apmEventClient } = setup; diff --git a/x-pack/plugins/apm/server/lib/services/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/services/__snapshots__/queries.test.ts.snap index d6d6219440dad..95bd6106b9ff2 100644 --- a/x-pack/plugins/apm/server/lib/services/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/services/__snapshots__/queries.test.ts.snap @@ -98,6 +98,9 @@ Object { }, }, "size": 1, + "sort": Object { + "_score": "desc", + }, }, "terminate_after": 1, } diff --git a/x-pack/plugins/apm/server/lib/services/get_service_agent.ts b/x-pack/plugins/apm/server/lib/services/get_service_agent.ts index 4c9ff9f124b10..dc3fee20fdf68 100644 --- a/x-pack/plugins/apm/server/lib/services/get_service_agent.ts +++ b/x-pack/plugins/apm/server/lib/services/get_service_agent.ts @@ -13,7 +13,6 @@ import { } from '../../../common/elasticsearch_fieldnames'; import { rangeQuery } from '../../../../observability/server'; import { Setup } from '../helpers/setup_request'; -import { getProcessorEventForTransactions } from '../helpers/transactions'; interface ServiceAgent { agent?: { @@ -29,13 +28,11 @@ interface ServiceAgent { export async function getServiceAgent({ serviceName, setup, - searchAggregatedTransactions, start, end, }: { serviceName: string; setup: Setup; - searchAggregatedTransactions: boolean; start: number; end: number; }) { @@ -46,7 +43,7 @@ export async function getServiceAgent({ apm: { events: [ ProcessorEvent.error, - getProcessorEventForTransactions(searchAggregatedTransactions), + ProcessorEvent.transaction, ProcessorEvent.metric, ], }, @@ -71,6 +68,9 @@ export async function getServiceAgent({ }, }, }, + sort: { + _score: 'desc' as const, + }, }, }; diff --git a/x-pack/plugins/apm/server/lib/services/get_service_infrastructure.ts b/x-pack/plugins/apm/server/lib/services/get_service_infrastructure.ts index 11669d5934303..09946187b90a2 100644 --- a/x-pack/plugins/apm/server/lib/services/get_service_infrastructure.ts +++ b/x-pack/plugins/apm/server/lib/services/get_service_infrastructure.ts @@ -6,7 +6,6 @@ */ import { Setup } from '../helpers/setup_request'; -import { ESFilter } from '../../../../../../src/core/types/elasticsearch'; import { rangeQuery, kqlQuery } from '../../../../observability/server'; import { environmentQuery } from '../../../common/utils/environment_query'; import { ProcessorEvent } from '../../../common/processor_event'; @@ -33,13 +32,6 @@ export const getServiceInfrastructure = async ({ }) => { const { apmEventClient } = setup; - const filter: ESFilter[] = [ - { term: { [SERVICE_NAME]: serviceName } }, - ...rangeQuery(start, end), - ...environmentQuery(environment), - ...kqlQuery(kuery), - ]; - const response = await apmEventClient.search('get_service_infrastructure', { apm: { events: [ProcessorEvent.metric], @@ -48,7 +40,12 @@ export const getServiceInfrastructure = async ({ size: 0, query: { bool: { - filter, + filter: [ + { term: { [SERVICE_NAME]: serviceName } }, + ...rangeQuery(start, end), + ...environmentQuery(environment), + ...kqlQuery(kuery), + ], }, }, aggs: { diff --git a/x-pack/plugins/apm/server/lib/services/get_throughput.ts b/x-pack/plugins/apm/server/lib/services/get_throughput.ts index e31e9dd3b8c9f..3161066ebadf9 100644 --- a/x-pack/plugins/apm/server/lib/services/get_throughput.ts +++ b/x-pack/plugins/apm/server/lib/services/get_throughput.ts @@ -5,20 +5,23 @@ * 2.0. */ -import { ESFilter } from '../../../../../../src/core/types/elasticsearch'; +import { AggregationsDateInterval } from '@elastic/elasticsearch/lib/api/types'; import { SERVICE_NAME, TRANSACTION_NAME, TRANSACTION_TYPE, } from '../../../common/elasticsearch_fieldnames'; -import { kqlQuery, rangeQuery } from '../../../../observability/server'; +import { + kqlQuery, + rangeQuery, + termQuery, +} from '../../../../observability/server'; import { environmentQuery } from '../../../common/utils/environment_query'; import { getDocumentTypeFilterForTransactions, getProcessorEventForTransactions, } from '../helpers/transactions'; import { Setup } from '../helpers/setup_request'; -import { calculateThroughputWithInterval } from '../helpers/calculate_throughput'; interface Options { environment: string; @@ -49,30 +52,27 @@ export async function getThroughput({ }: Options) { const { apmEventClient } = setup; - const filter: ESFilter[] = [ - { term: { [SERVICE_NAME]: serviceName } }, - { term: { [TRANSACTION_TYPE]: transactionType } }, - ...getDocumentTypeFilterForTransactions(searchAggregatedTransactions), - ...rangeQuery(start, end), - ...environmentQuery(environment), - ...kqlQuery(kuery), - ]; - - if (transactionName) { - filter.push({ - term: { - [TRANSACTION_NAME]: transactionName, - }, - }); - } - const params = { apm: { events: [getProcessorEventForTransactions(searchAggregatedTransactions)], }, body: { size: 0, - query: { bool: { filter } }, + query: { + bool: { + filter: [ + { term: { [SERVICE_NAME]: serviceName } }, + { term: { [TRANSACTION_TYPE]: transactionType } }, + ...getDocumentTypeFilterForTransactions( + searchAggregatedTransactions + ), + ...rangeQuery(start, end), + ...environmentQuery(environment), + ...kqlQuery(kuery), + ...termQuery(TRANSACTION_NAME, transactionName), + ], + }, + }, aggs: { timeseries: { date_histogram: { @@ -81,6 +81,11 @@ export async function getThroughput({ min_doc_count: 0, extended_bounds: { min: start, max: end }, }, + aggs: { + throughput: { + rate: { unit: 'minute' as AggregationsDateInterval }, + }, + }, }, }, }, @@ -95,10 +100,7 @@ export async function getThroughput({ response.aggregations?.timeseries.buckets.map((bucket) => { return { x: bucket.key, - y: calculateThroughputWithInterval({ - bucketSize, - value: bucket.doc_count, - }), + y: bucket.throughput.value, }; }) ?? [] ); diff --git a/x-pack/plugins/apm/server/lib/services/queries.test.ts b/x-pack/plugins/apm/server/lib/services/queries.test.ts index 4ed6f856d735b..30d89214959da 100644 --- a/x-pack/plugins/apm/server/lib/services/queries.test.ts +++ b/x-pack/plugins/apm/server/lib/services/queries.test.ts @@ -28,7 +28,6 @@ describe('services queries', () => { getServiceAgent({ serviceName: 'foo', setup, - searchAggregatedTransactions: false, start: 0, end: 50000, }) diff --git a/x-pack/plugins/apm/server/lib/transaction_groups/fetcher.ts b/x-pack/plugins/apm/server/lib/transaction_groups/fetcher.ts index 200d3d6ac7459..aea92d06b7589 100644 --- a/x-pack/plugins/apm/server/lib/transaction_groups/fetcher.ts +++ b/x-pack/plugins/apm/server/lib/transaction_groups/fetcher.ts @@ -10,7 +10,11 @@ import { sortBy } from 'lodash'; import moment from 'moment'; import { Unionize } from 'utility-types'; import { AggregationOptionsByType } from '../../../../../../src/core/types/elasticsearch'; -import { kqlQuery, rangeQuery } from '../../../../observability/server'; +import { + kqlQuery, + rangeQuery, + termQuery, +} from '../../../../observability/server'; import { PARENT_ID, SERVICE_NAME, @@ -69,10 +73,6 @@ function getRequest(topTraceOptions: TopTraceOptions) { end, } = topTraceOptions; - const transactionNameFilter = transactionName - ? [{ term: { [TRANSACTION_NAME]: transactionName } }] - : []; - return { apm: { events: [getProcessorEventForTransactions(searchAggregatedTransactions)], @@ -82,7 +82,7 @@ function getRequest(topTraceOptions: TopTraceOptions) { query: { bool: { filter: [ - ...transactionNameFilter, + ...termQuery(TRANSACTION_NAME, transactionName), ...getDocumentTypeFilterForTransactions( searchAggregatedTransactions ), diff --git a/x-pack/plugins/apm/server/lib/transaction_groups/get_error_rate.ts b/x-pack/plugins/apm/server/lib/transaction_groups/get_error_rate.ts index b7318e81a84a3..328d2da0f6df0 100644 --- a/x-pack/plugins/apm/server/lib/transaction_groups/get_error_rate.ts +++ b/x-pack/plugins/apm/server/lib/transaction_groups/get_error_rate.ts @@ -13,7 +13,11 @@ import { } from '../../../common/elasticsearch_fieldnames'; import { EventOutcome } from '../../../common/event_outcome'; import { offsetPreviousPeriodCoordinates } from '../../../common/utils/offset_previous_period_coordinate'; -import { kqlQuery, rangeQuery } from '../../../../observability/server'; +import { + kqlQuery, + rangeQuery, + termQuery, +} from '../../../../observability/server'; import { environmentQuery } from '../../../common/utils/environment_query'; import { Coordinate } from '../../../typings/timeseries'; import { @@ -54,13 +58,6 @@ export async function getErrorRate({ }> { const { apmEventClient } = setup; - const transactionNamefilter = transactionName - ? [{ term: { [TRANSACTION_NAME]: transactionName } }] - : []; - const transactionTypefilter = transactionType - ? [{ term: { [TRANSACTION_TYPE]: transactionType } }] - : []; - const filter = [ { term: { [SERVICE_NAME]: serviceName } }, { @@ -68,8 +65,8 @@ export async function getErrorRate({ [EVENT_OUTCOME]: [EventOutcome.failure, EventOutcome.success], }, }, - ...transactionNamefilter, - ...transactionTypefilter, + ...termQuery(TRANSACTION_NAME, transactionName), + ...termQuery(TRANSACTION_TYPE, transactionType), ...getDocumentTypeFilterForTransactions(searchAggregatedTransactions), ...rangeQuery(start, end), ...environmentQuery(environment), diff --git a/x-pack/plugins/apm/server/lib/transactions/get_latency_charts/index.ts b/x-pack/plugins/apm/server/lib/transactions/get_latency_charts/index.ts index c4bae841764cf..4612d399b54a1 100644 --- a/x-pack/plugins/apm/server/lib/transactions/get_latency_charts/index.ts +++ b/x-pack/plugins/apm/server/lib/transactions/get_latency_charts/index.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { ESFilter } from '../../../../../../../src/core/types/elasticsearch'; import { PromiseReturnType } from '../../../../../observability/typings/common'; import { SERVICE_NAME, @@ -14,7 +13,11 @@ import { } from '../../../../common/elasticsearch_fieldnames'; import { LatencyAggregationType } from '../../../../common/latency_aggregation_types'; import { offsetPreviousPeriodCoordinates } from '../../../../common/utils/offset_previous_period_coordinate'; -import { kqlQuery, rangeQuery } from '../../../../../observability/server'; +import { + kqlQuery, + rangeQuery, + termQuery, +} from '../../../../../observability/server'; import { environmentQuery } from '../../../../common/utils/environment_query'; import { getDocumentTypeFilterForTransactions, @@ -61,22 +64,6 @@ function searchLatency({ searchAggregatedTransactions, }); - const filter: ESFilter[] = [ - { term: { [SERVICE_NAME]: serviceName } }, - ...getDocumentTypeFilterForTransactions(searchAggregatedTransactions), - ...rangeQuery(start, end), - ...environmentQuery(environment), - ...kqlQuery(kuery), - ]; - - if (transactionName) { - filter.push({ term: { [TRANSACTION_NAME]: transactionName } }); - } - - if (transactionType) { - filter.push({ term: { [TRANSACTION_TYPE]: transactionType } }); - } - const transactionDurationField = getTransactionDurationFieldForTransactions( searchAggregatedTransactions ); @@ -87,7 +74,21 @@ function searchLatency({ }, body: { size: 0, - query: { bool: { filter } }, + query: { + bool: { + filter: [ + { term: { [SERVICE_NAME]: serviceName } }, + ...getDocumentTypeFilterForTransactions( + searchAggregatedTransactions + ), + ...rangeQuery(start, end), + ...environmentQuery(environment), + ...kqlQuery(kuery), + ...termQuery(TRANSACTION_NAME, transactionName), + ...termQuery(TRANSACTION_TYPE, transactionType), + ], + }, + }, aggs: { latencyTimeseries: { date_histogram: { diff --git a/x-pack/plugins/apm/server/lib/transactions/get_transaction/index.ts b/x-pack/plugins/apm/server/lib/transactions/get_transaction/index.ts index e5d8c930393e0..6d0bbcdb55ca4 100644 --- a/x-pack/plugins/apm/server/lib/transactions/get_transaction/index.ts +++ b/x-pack/plugins/apm/server/lib/transactions/get_transaction/index.ts @@ -9,7 +9,7 @@ import { TRACE_ID, TRANSACTION_ID, } from '../../../../common/elasticsearch_fieldnames'; -import { rangeQuery } from '../../../../../observability/server'; +import { rangeQuery, termQuery } from '../../../../../observability/server'; import { Setup } from '../../helpers/setup_request'; import { ProcessorEvent } from '../../../../common/processor_event'; import { asMutableArray } from '../../../../common/utils/as_mutable_array'; @@ -39,7 +39,7 @@ export async function getTransaction({ bool: { filter: asMutableArray([ { term: { [TRANSACTION_ID]: transactionId } }, - ...(traceId ? [{ term: { [TRACE_ID]: traceId } }] : []), + ...termQuery(TRACE_ID, traceId), ...(start && end ? rangeQuery(start, end) : []), ]), }, diff --git a/x-pack/plugins/apm/server/projections/services.ts b/x-pack/plugins/apm/server/projections/services.ts deleted file mode 100644 index 139c86acd5144..0000000000000 --- a/x-pack/plugins/apm/server/projections/services.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { Setup } from '../../server/lib/helpers/setup_request'; -import { SERVICE_NAME } from '../../common/elasticsearch_fieldnames'; -import { rangeQuery, kqlQuery } from '../../../observability/server'; -import { ProcessorEvent } from '../../common/processor_event'; -import { getProcessorEventForTransactions } from '../lib/helpers/transactions'; - -export function getServicesProjection({ - kuery, - setup, - searchAggregatedTransactions, - start, - end, -}: { - kuery: string; - setup: Setup; - searchAggregatedTransactions: boolean; - start: number; - end: number; -}) { - return { - apm: { - events: [ - getProcessorEventForTransactions(searchAggregatedTransactions), - ProcessorEvent.metric as const, - ProcessorEvent.error as const, - ], - }, - body: { - size: 0, - query: { - bool: { - filter: [...rangeQuery(start, end), ...kqlQuery(kuery)], - }, - }, - aggs: { - services: { - terms: { - field: SERVICE_NAME, - }, - }, - }, - }, - }; -} diff --git a/x-pack/plugins/apm/server/routes/services.ts b/x-pack/plugins/apm/server/routes/services.ts index 257aec216eb06..3af829d59d3fd 100644 --- a/x-pack/plugins/apm/server/routes/services.ts +++ b/x-pack/plugins/apm/server/routes/services.ts @@ -191,18 +191,9 @@ const serviceAgentRoute = createApmServerRoute({ const { serviceName } = params.path; const { start, end } = params.query; - const searchAggregatedTransactions = await getSearchAggregatedTransactions({ - apmEventClient: setup.apmEventClient, - config: setup.config, - start, - end, - kuery: '', - }); - return getServiceAgent({ serviceName, setup, - searchAggregatedTransactions, start, end, }); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/expression_types/embeddable.ts b/x-pack/plugins/canvas/canvas_plugin_src/expression_types/embeddable.ts index 66cb95a4a210a..1f447c7ed834e 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/expression_types/embeddable.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/expression_types/embeddable.ts @@ -6,7 +6,7 @@ */ import { ExpressionTypeDefinition } from '../../../../../src/plugins/expressions'; -import { EmbeddableInput } from '../../../../../src/plugins/embeddable/common/'; +import { EmbeddableInput } from '../../types'; import { EmbeddableTypes } from './embeddable_types'; export const EmbeddableExpressionType = 'embeddable'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/index.ts index 2cfdebafb70df..d6d7a0f867849 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/index.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/index.ts @@ -6,7 +6,6 @@ */ import { functions as commonFunctions } from '../common'; -import { functions as externalFunctions } from '../external'; import { location } from './location'; import { markdown } from './markdown'; import { urlparam } from './urlparam'; @@ -14,13 +13,4 @@ import { escount } from './escount'; import { esdocs } from './esdocs'; import { essql } from './essql'; -export const functions = [ - location, - markdown, - urlparam, - escount, - esdocs, - essql, - ...commonFunctions, - ...externalFunctions, -]; +export const functions = [location, markdown, urlparam, escount, esdocs, essql, ...commonFunctions]; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.test.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.test.ts new file mode 100644 index 0000000000000..001fb0e3f62e3 --- /dev/null +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.test.ts @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { embeddableFunctionFactory } from './embeddable'; +import { getQueryFilters } from '../../../common/lib/build_embeddable_filters'; +import { ExpressionValueFilter } from '../../../types'; +import { encode } from '../../../common/lib/embeddable_dataurl'; +import { InitializeArguments } from '.'; + +const filterContext: ExpressionValueFilter = { + type: 'filter', + and: [ + { + type: 'filter', + and: [], + value: 'filter-value', + column: 'filter-column', + filterType: 'exactly', + }, + { + type: 'filter', + and: [], + column: 'time-column', + filterType: 'time', + from: '2019-06-04T04:00:00.000Z', + to: '2019-06-05T04:00:00.000Z', + }, + ], +}; + +describe('embeddable', () => { + const fn = embeddableFunctionFactory({} as InitializeArguments)().fn; + const config = { + id: 'some-id', + timerange: { from: '15m', to: 'now' }, + title: 'test embeddable', + }; + + const args = { + config: encode(config), + type: 'visualization', + }; + + it('accepts null context', () => { + const expression = fn(null, args, {} as any); + + expect(expression.input.filters).toEqual([]); + }); + + it('accepts filter context', () => { + const expression = fn(filterContext, args, {} as any); + const embeddableFilters = getQueryFilters(filterContext.and); + + expect(expression.input.filters).toEqual(embeddableFilters); + }); +}); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts new file mode 100644 index 0000000000000..7ef8f0a09eb90 --- /dev/null +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts @@ -0,0 +1,145 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common'; +import { ExpressionValueFilter, EmbeddableInput } from '../../../types'; +import { EmbeddableExpressionType, EmbeddableExpression } from '../../expression_types'; +import { getFunctionHelp } from '../../../i18n'; +import { SavedObjectReference } from '../../../../../../src/core/types'; +import { getQueryFilters } from '../../../common/lib/build_embeddable_filters'; +import { decode, encode } from '../../../common/lib/embeddable_dataurl'; +import { InitializeArguments } from '.'; + +export interface Arguments { + config: string; + type: string; +} + +const defaultTimeRange = { + from: 'now-15m', + to: 'now', +}; + +const baseEmbeddableInput = { + timeRange: defaultTimeRange, + disableTriggers: true, + renderMode: 'noInteractivity', +}; + +type Return = EmbeddableExpression; + +type EmbeddableFunction = ExpressionFunctionDefinition< + 'embeddable', + ExpressionValueFilter | null, + Arguments, + Return +>; + +export function embeddableFunctionFactory({ + embeddablePersistableStateService, +}: InitializeArguments): () => EmbeddableFunction { + return function embeddable(): EmbeddableFunction { + const { help, args: argHelp } = getFunctionHelp().embeddable; + + return { + name: 'embeddable', + help, + args: { + config: { + aliases: ['_'], + types: ['string'], + required: true, + help: argHelp.config, + }, + type: { + types: ['string'], + required: true, + help: argHelp.type, + }, + }, + context: { + types: ['filter'], + }, + type: EmbeddableExpressionType, + fn: (input, args) => { + const filters = input ? input.and : []; + + const embeddableInput = decode(args.config) as EmbeddableInput; + + return { + type: EmbeddableExpressionType, + input: { + ...baseEmbeddableInput, + ...embeddableInput, + filters: getQueryFilters(filters), + }, + generatedAt: Date.now(), + embeddableType: args.type, + }; + }, + + extract(state) { + const input = decode(state.config[0] as string); + + // extracts references for by-reference embeddables + if (input.savedObjectId) { + const refName = 'embeddable.savedObjectId'; + + const references: SavedObjectReference[] = [ + { + name: refName, + type: state.type[0] as string, + id: input.savedObjectId as string, + }, + ]; + + return { + state, + references, + }; + } + + // extracts references for by-value embeddables + const { state: extractedState, references: extractedReferences } = + embeddablePersistableStateService.extract({ + ...input, + type: state.type[0], + }); + + const { type, ...extractedInput } = extractedState; + + return { + state: { ...state, config: [encode(extractedInput)], type: [type] }, + references: extractedReferences, + }; + }, + + inject(state, references) { + const input = decode(state.config[0] as string); + const savedObjectReference = references.find( + (ref) => ref.name === 'embeddable.savedObjectId' + ); + + // injects saved object id for by-references embeddable + if (savedObjectReference) { + input.savedObjectId = savedObjectReference.id; + state.config[0] = encode(input); + state.type[0] = savedObjectReference.type; + } else { + // injects references for by-value embeddables + const { type, ...injectedInput } = embeddablePersistableStateService.inject( + { ...input, type: state.type[0] }, + references + ); + state.config[0] = encode(injectedInput); + state.type[0] = type; + } + return state; + }, + }; + }; +} diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/index.ts index 407a0e2ebfe05..1d69e181b5fd9 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/index.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/index.ts @@ -5,9 +5,26 @@ * 2.0. */ +import { EmbeddableStart } from 'src/plugins/embeddable/public'; +import { embeddableFunctionFactory } from './embeddable'; import { savedLens } from './saved_lens'; import { savedMap } from './saved_map'; import { savedSearch } from './saved_search'; import { savedVisualization } from './saved_visualization'; -export const functions = [savedLens, savedMap, savedVisualization, savedSearch]; +export interface InitializeArguments { + embeddablePersistableStateService: { + extract: EmbeddableStart['extract']; + inject: EmbeddableStart['inject']; + }; +} + +export function initFunctions(initialize: InitializeArguments) { + return [ + embeddableFunctionFactory(initialize), + savedLens, + savedMap, + savedSearch, + savedVisualization, + ]; +} diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_lens.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_lens.ts index 082a69a874cae..67947691f7757 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_lens.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_lens.ts @@ -9,9 +9,8 @@ import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common'; import { PaletteOutput } from 'src/plugins/charts/common'; import { Filter as DataFilter } from '@kbn/es-query'; import { TimeRange } from 'src/plugins/data/common'; -import { EmbeddableInput } from 'src/plugins/embeddable/common'; import { getQueryFilters } from '../../../common/lib/build_embeddable_filters'; -import { ExpressionValueFilter, TimeRange as TimeRangeArg } from '../../../types'; +import { ExpressionValueFilter, EmbeddableInput, TimeRange as TimeRangeArg } from '../../../types'; import { EmbeddableTypes, EmbeddableExpressionType, @@ -27,7 +26,7 @@ interface Arguments { } export type SavedLensInput = EmbeddableInput & { - id: string; + savedObjectId: string; timeRange?: TimeRange; filters: DataFilter[]; palette?: PaletteOutput; @@ -73,18 +72,19 @@ export function savedLens(): ExpressionFunctionDefinition< }, }, type: EmbeddableExpressionType, - fn: (input, args) => { + fn: (input, { id, timerange, title, palette }) => { const filters = input ? input.and : []; return { type: EmbeddableExpressionType, input: { - id: args.id, + id, + savedObjectId: id, filters: getQueryFilters(filters), - timeRange: args.timerange || defaultTimeRange, - title: args.title === null ? undefined : args.title, + timeRange: timerange || defaultTimeRange, + title: title === null ? undefined : title, disableTriggers: true, - palette: args.palette, + palette, }, embeddableType: EmbeddableTypes.lens, generatedAt: Date.now(), diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_map.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_map.ts index 538ed3f919823..a7471c755155c 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_map.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_map.ts @@ -30,7 +30,7 @@ const defaultTimeRange = { to: 'now', }; -type Output = EmbeddableExpression; +type Output = EmbeddableExpression; export function savedMap(): ExpressionFunctionDefinition< 'savedMap', @@ -85,8 +85,9 @@ export function savedMap(): ExpressionFunctionDefinition< return { type: EmbeddableExpressionType, input: { - attributes: { title: '' }, id: args.id, + attributes: { title: '' }, + savedObjectId: args.id, filters: getQueryFilters(filters), timeRange: args.timerange || defaultTimeRange, refreshConfig: { diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_visualization.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_visualization.ts index 5c0442b43250c..31e3fb2a8c564 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_visualization.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_visualization.ts @@ -25,7 +25,7 @@ interface Arguments { title: string | null; } -type Output = EmbeddableExpression; +type Output = EmbeddableExpression; const defaultTimeRange = { from: 'now-15m', @@ -94,6 +94,7 @@ export function savedVisualization(): ExpressionFunctionDefinition< type: EmbeddableExpressionType, input: { id, + savedObjectId: id, disableTriggers: true, timeRange: timerange || defaultTimeRange, filters: getQueryFilters(filters), diff --git a/x-pack/plugins/canvas/canvas_plugin_src/plugin.ts b/x-pack/plugins/canvas/canvas_plugin_src/plugin.ts index 91c573fc4148b..591795637aebe 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/plugin.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/plugin.ts @@ -7,12 +7,14 @@ import { CoreSetup, CoreStart, Plugin } from 'src/core/public'; import { ChartsPluginStart } from 'src/plugins/charts/public'; +import { PresentationUtilPluginStart } from 'src/plugins/presentation_util/public'; import { CanvasSetup } from '../public'; import { EmbeddableStart } from '../../../../src/plugins/embeddable/public'; import { UiActionsStart } from '../../../../src/plugins/ui_actions/public'; import { Start as InspectorStart } from '../../../../src/plugins/inspector/public'; import { functions } from './functions/browser'; +import { initFunctions } from './functions/external'; import { typeFunctions } from './expression_types'; import { renderFunctions, renderFunctionFactories } from './renderers'; @@ -25,6 +27,7 @@ export interface StartDeps { uiActions: UiActionsStart; inspector: InspectorStart; charts: ChartsPluginStart; + presentationUtil: PresentationUtilPluginStart; } export type SetupInitializer = (core: CoreSetup, plugins: SetupDeps) => T; @@ -39,6 +42,13 @@ export class CanvasSrcPlugin implements Plugin plugins.canvas.addRenderers(renderFunctions); core.getStartServices().then(([coreStart, depsStart]) => { + const externalFunctions = initFunctions({ + embeddablePersistableStateService: { + extract: depsStart.embeddable.extract, + inject: depsStart.embeddable.inject, + }, + }); + plugins.canvas.addFunctions(externalFunctions); plugins.canvas.addRenderers( renderFunctionFactories.map((factory: any) => factory(coreStart, depsStart)) ); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx index 73e839433c25e..953746c280840 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx @@ -13,16 +13,17 @@ import { IEmbeddable, EmbeddableFactory, EmbeddableFactoryNotFoundError, + isErrorEmbeddable, } from '../../../../../../src/plugins/embeddable/public'; import { EmbeddableExpression } from '../../expression_types/embeddable'; import { RendererStrings } from '../../../i18n'; import { embeddableInputToExpression } from './embeddable_input_to_expression'; -import { EmbeddableInput } from '../../expression_types'; -import { RendererFactory } from '../../../types'; +import { RendererFactory, EmbeddableInput } from '../../../types'; import { CANVAS_EMBEDDABLE_CLASSNAME } from '../../../common/lib'; const { embeddable: strings } = RendererStrings; +// registry of references to embeddables on the workpad const embeddablesRegistry: { [key: string]: IEmbeddable | Promise; } = {}; @@ -30,11 +31,11 @@ const embeddablesRegistry: { const renderEmbeddableFactory = (core: CoreStart, plugins: StartDeps) => { const I18nContext = core.i18n.Context; - return (embeddableObject: IEmbeddable, domNode: HTMLElement) => { + return (embeddableObject: IEmbeddable) => { return (
@@ -56,6 +57,9 @@ export const embeddableRendererFactory = ( reuseDomNode: true, render: async (domNode, { input, embeddableType }, handlers) => { const uniqueId = handlers.getElementId(); + const isByValueEnabled = plugins.presentationUtil.labsService.isProjectEnabled( + 'labs:canvas:byValueEmbeddable' + ); if (!embeddablesRegistry[uniqueId]) { const factory = Array.from(plugins.embeddable.getEmbeddableFactories()).find( @@ -67,15 +71,27 @@ export const embeddableRendererFactory = ( throw new EmbeddableFactoryNotFoundError(embeddableType); } - const embeddablePromise = factory - .createFromSavedObject(input.id, input) - .then((embeddable) => { - embeddablesRegistry[uniqueId] = embeddable; - return embeddable; - }); - embeddablesRegistry[uniqueId] = embeddablePromise; - - const embeddableObject = await (async () => embeddablePromise)(); + const embeddableInput = { ...input, id: uniqueId }; + + const embeddablePromise = input.savedObjectId + ? factory + .createFromSavedObject(input.savedObjectId, embeddableInput) + .then((embeddable) => { + // stores embeddable in registrey + embeddablesRegistry[uniqueId] = embeddable; + return embeddable; + }) + : factory.create(embeddableInput).then((embeddable) => { + if (!embeddable || isErrorEmbeddable(embeddable)) { + return; + } + // stores embeddable in registry + embeddablesRegistry[uniqueId] = embeddable as IEmbeddable; + return embeddable; + }); + embeddablesRegistry[uniqueId] = embeddablePromise as Promise; + + const embeddableObject = (await (async () => embeddablePromise)()) as IEmbeddable; const palettes = await plugins.charts.palettes.getPalettes(); @@ -86,7 +102,8 @@ export const embeddableRendererFactory = ( const updatedExpression = embeddableInputToExpression( updatedInput, embeddableType, - palettes + palettes, + isByValueEnabled ); if (updatedExpression) { @@ -94,15 +111,7 @@ export const embeddableRendererFactory = ( } }); - ReactDOM.render(renderEmbeddable(embeddableObject, domNode), domNode, () => - handlers.done() - ); - - handlers.onResize(() => { - ReactDOM.render(renderEmbeddable(embeddableObject, domNode), domNode, () => - handlers.done() - ); - }); + ReactDOM.render(renderEmbeddable(embeddableObject), domNode, () => handlers.done()); handlers.onDestroy(() => { subscription.unsubscribe(); @@ -115,6 +124,7 @@ export const embeddableRendererFactory = ( } else { const embeddable = embeddablesRegistry[uniqueId]; + // updating embeddable input with changes made to expression or filters if ('updateInput' in embeddable) { embeddable.updateInput(input); embeddable.reload(); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable_input_to_expression.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable_input_to_expression.ts index 41cefad6a470f..80830eac24021 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable_input_to_expression.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable_input_to_expression.ts @@ -10,6 +10,7 @@ import { EmbeddableTypes, EmbeddableInput } from '../../expression_types'; import { toExpression as mapToExpression } from './input_type_to_expression/map'; import { toExpression as visualizationToExpression } from './input_type_to_expression/visualization'; import { toExpression as lensToExpression } from './input_type_to_expression/lens'; +import { toExpression as genericToExpression } from './input_type_to_expression/embeddable'; export const inputToExpressionTypeMap = { [EmbeddableTypes.map]: mapToExpression, @@ -23,8 +24,13 @@ export const inputToExpressionTypeMap = { export function embeddableInputToExpression( input: EmbeddableInput, embeddableType: string, - palettes: PaletteRegistry + palettes: PaletteRegistry, + useGenericEmbeddable?: boolean ): string | undefined { + if (useGenericEmbeddable) { + return genericToExpression(input, embeddableType); + } + if (inputToExpressionTypeMap[embeddableType]) { return inputToExpressionTypeMap[embeddableType](input as any, palettes); } diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/embeddable.test.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/embeddable.test.ts new file mode 100644 index 0000000000000..4b78acec8750a --- /dev/null +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/embeddable.test.ts @@ -0,0 +1,128 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { toExpression } from './embeddable'; +import { EmbeddableInput } from '../../../../types'; +import { decode } from '../../../../common/lib/embeddable_dataurl'; +import { fromExpression } from '@kbn/interpreter/common'; + +describe('toExpression', () => { + describe('by-reference embeddable input', () => { + const baseEmbeddableInput = { + id: 'elementId', + savedObjectId: 'embeddableId', + filters: [], + }; + + it('converts to an embeddable expression', () => { + const input: EmbeddableInput = baseEmbeddableInput; + + const expression = toExpression(input, 'visualization'); + const ast = fromExpression(expression); + + expect(ast.type).toBe('expression'); + expect(ast.chain[0].function).toBe('embeddable'); + expect(ast.chain[0].arguments.type[0]).toBe('visualization'); + + const config = decode(ast.chain[0].arguments.config[0] as string); + + expect(config.savedObjectId).toStrictEqual(input.savedObjectId); + }); + + it('includes optional input values', () => { + const input: EmbeddableInput = { + ...baseEmbeddableInput, + title: 'title', + timeRange: { + from: 'now-1h', + to: 'now', + }, + }; + + const expression = toExpression(input, 'visualization'); + const ast = fromExpression(expression); + + const config = decode(ast.chain[0].arguments.config[0] as string); + + expect(config).toHaveProperty('title', input.title); + expect(config).toHaveProperty('timeRange'); + expect(config.timeRange).toHaveProperty('from', input.timeRange?.from); + expect(config.timeRange).toHaveProperty('to', input.timeRange?.to); + }); + + it('includes empty panel title', () => { + const input: EmbeddableInput = { + ...baseEmbeddableInput, + title: '', + }; + + const expression = toExpression(input, 'visualization'); + const ast = fromExpression(expression); + + const config = decode(ast.chain[0].arguments.config[0] as string); + + expect(config).toHaveProperty('title', input.title); + }); + }); + + describe('by-value embeddable input', () => { + const baseEmbeddableInput = { + id: 'elementId', + disableTriggers: true, + filters: [], + }; + it('converts to an embeddable expression', () => { + const input: EmbeddableInput = baseEmbeddableInput; + + const expression = toExpression(input, 'visualization'); + const ast = fromExpression(expression); + + expect(ast.type).toBe('expression'); + expect(ast.chain[0].function).toBe('embeddable'); + expect(ast.chain[0].arguments.type[0]).toBe('visualization'); + + const config = decode(ast.chain[0].arguments.config[0] as string); + expect(config.filters).toStrictEqual(input.filters); + expect(config.disableTriggers).toStrictEqual(input.disableTriggers); + }); + + it('includes optional input values', () => { + const input: EmbeddableInput = { + ...baseEmbeddableInput, + title: 'title', + timeRange: { + from: 'now-1h', + to: 'now', + }, + }; + + const expression = toExpression(input, 'visualization'); + const ast = fromExpression(expression); + + const config = decode(ast.chain[0].arguments.config[0] as string); + + expect(config).toHaveProperty('title', input.title); + expect(config).toHaveProperty('timeRange'); + expect(config.timeRange).toHaveProperty('from', input.timeRange?.from); + expect(config.timeRange).toHaveProperty('to', input.timeRange?.to); + }); + + it('includes empty panel title', () => { + const input: EmbeddableInput = { + ...baseEmbeddableInput, + title: '', + }; + + const expression = toExpression(input, 'visualization'); + const ast = fromExpression(expression); + + const config = decode(ast.chain[0].arguments.config[0] as string); + + expect(config).toHaveProperty('title', input.title); + }); + }); +}); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/embeddable.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/embeddable.ts new file mode 100644 index 0000000000000..94d86f6640be1 --- /dev/null +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/embeddable.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { encode } from '../../../../common/lib/embeddable_dataurl'; +import { EmbeddableInput } from '../../../expression_types'; + +export function toExpression(input: EmbeddableInput, embeddableType: string): string { + return `embeddable config="${encode(input)}" type="${embeddableType}"`; +} diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/lens.test.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/lens.test.ts index 24da7238bcee9..224cdfba389d7 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/lens.test.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/lens.test.ts @@ -11,7 +11,8 @@ import { fromExpression, Ast } from '@kbn/interpreter/common'; import { chartPluginMock } from 'src/plugins/charts/public/mocks'; const baseEmbeddableInput = { - id: 'embeddableId', + id: 'elementId', + savedObjectId: 'embeddableId', filters: [], }; @@ -27,7 +28,7 @@ describe('toExpression', () => { expect(ast.type).toBe('expression'); expect(ast.chain[0].function).toBe('savedLens'); - expect(ast.chain[0].arguments.id).toStrictEqual([input.id]); + expect(ast.chain[0].arguments.id).toStrictEqual([input.savedObjectId]); expect(ast.chain[0].arguments).not.toHaveProperty('title'); expect(ast.chain[0].arguments).not.toHaveProperty('timerange'); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/lens.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/lens.ts index 35e106f234fa4..5a13b73b3fe74 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/lens.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/lens.ts @@ -14,7 +14,7 @@ export function toExpression(input: SavedLensInput, palettes: PaletteRegistry): expressionParts.push('savedLens'); - expressionParts.push(`id="${input.id}"`); + expressionParts.push(`id="${input.savedObjectId}"`); if (input.title !== undefined) { expressionParts.push(`title="${input.title}"`); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/map.test.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/map.test.ts index 804d0d849cc7f..af7b40a9b283d 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/map.test.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/map.test.ts @@ -6,12 +6,12 @@ */ import { toExpression } from './map'; -import { MapEmbeddableInput } from '../../../../../../plugins/maps/public/embeddable'; import { fromExpression, Ast } from '@kbn/interpreter/common'; const baseSavedMapInput = { + id: 'elementId', attributes: { title: '' }, - id: 'embeddableId', + savedObjectId: 'embeddableId', filters: [], isLayerTOCOpen: false, refreshConfig: { @@ -23,7 +23,7 @@ const baseSavedMapInput = { describe('toExpression', () => { it('converts to a savedMap expression', () => { - const input: MapEmbeddableInput = { + const input = { ...baseSavedMapInput, }; @@ -33,7 +33,7 @@ describe('toExpression', () => { expect(ast.type).toBe('expression'); expect(ast.chain[0].function).toBe('savedMap'); - expect(ast.chain[0].arguments.id).toStrictEqual([input.id]); + expect(ast.chain[0].arguments.id).toStrictEqual([input.savedObjectId]); expect(ast.chain[0].arguments).not.toHaveProperty('title'); expect(ast.chain[0].arguments).not.toHaveProperty('center'); @@ -41,7 +41,7 @@ describe('toExpression', () => { }); it('includes optional input values', () => { - const input: MapEmbeddableInput = { + const input = { ...baseSavedMapInput, mapCenter: { lat: 1, @@ -73,7 +73,7 @@ describe('toExpression', () => { }); it('includes empty panel title', () => { - const input: MapEmbeddableInput = { + const input = { ...baseSavedMapInput, title: '', }; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/map.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/map.ts index 3fd6a68a327c6..03746f38b4696 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/map.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/map.ts @@ -5,13 +5,14 @@ * 2.0. */ -import { MapEmbeddableInput } from '../../../../../../plugins/maps/public/embeddable'; +import { MapEmbeddableInput } from '../../../../../../plugins/maps/public'; -export function toExpression(input: MapEmbeddableInput): string { +export function toExpression(input: MapEmbeddableInput & { savedObjectId: string }): string { const expressionParts = [] as string[]; expressionParts.push('savedMap'); - expressionParts.push(`id="${input.id}"`); + + expressionParts.push(`id="${input.savedObjectId}"`); if (input.title !== undefined) { expressionParts.push(`title="${input.title}"`); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/visualization.test.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/visualization.test.ts index c5106b9a102b4..4c61a130f3c95 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/visualization.test.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/visualization.test.ts @@ -9,7 +9,8 @@ import { toExpression } from './visualization'; import { fromExpression, Ast } from '@kbn/interpreter/common'; const baseInput = { - id: 'embeddableId', + id: 'elementId', + savedObjectId: 'embeddableId', }; describe('toExpression', () => { @@ -24,7 +25,7 @@ describe('toExpression', () => { expect(ast.type).toBe('expression'); expect(ast.chain[0].function).toBe('savedVisualization'); - expect(ast.chain[0].arguments.id).toStrictEqual([input.id]); + expect(ast.chain[0].arguments.id).toStrictEqual([input.savedObjectId]); }); it('includes timerange if given', () => { diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/visualization.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/visualization.ts index bcb73b2081fee..364d7cd0755db 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/visualization.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/visualization.ts @@ -7,11 +7,11 @@ import { VisualizeInput } from 'src/plugins/visualizations/public'; -export function toExpression(input: VisualizeInput): string { +export function toExpression(input: VisualizeInput & { savedObjectId: string }): string { const expressionParts = [] as string[]; expressionParts.push('savedVisualization'); - expressionParts.push(`id="${input.id}"`); + expressionParts.push(`id="${input.savedObjectId}"`); if (input.title !== undefined) { expressionParts.push(`title="${input.title}"`); diff --git a/x-pack/plugins/canvas/common/lib/embeddable_dataurl.ts b/x-pack/plugins/canvas/common/lib/embeddable_dataurl.ts new file mode 100644 index 0000000000000..e76dedfe63b14 --- /dev/null +++ b/x-pack/plugins/canvas/common/lib/embeddable_dataurl.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EmbeddableInput } from '../../types'; + +export const encode = (input: Partial) => + Buffer.from(JSON.stringify(input)).toString('base64'); +export const decode = (serializedInput: string) => + JSON.parse(Buffer.from(serializedInput, 'base64').toString()); diff --git a/x-pack/plugins/canvas/i18n/functions/dict/embeddable.ts b/x-pack/plugins/canvas/i18n/functions/dict/embeddable.ts new file mode 100644 index 0000000000000..279f58799e8c0 --- /dev/null +++ b/x-pack/plugins/canvas/i18n/functions/dict/embeddable.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { embeddableFunctionFactory } from '../../../canvas_plugin_src/functions/external/embeddable'; +import { FunctionHelp } from '../function_help'; +import { FunctionFactory } from '../../../types'; + +export const help: FunctionHelp>> = { + help: i18n.translate('xpack.canvas.functions.embeddableHelpText', { + defaultMessage: `Returns an embeddable with the provided configuration`, + }), + args: { + config: i18n.translate('xpack.canvas.functions.embeddable.args.idHelpText', { + defaultMessage: `The base64 encoded embeddable input object`, + }), + type: i18n.translate('xpack.canvas.functions.embeddable.args.typeHelpText', { + defaultMessage: `The embeddable type`, + }), + }, +}; diff --git a/x-pack/plugins/canvas/i18n/functions/function_help.ts b/x-pack/plugins/canvas/i18n/functions/function_help.ts index 5eae785fefa2e..520d32af1c272 100644 --- a/x-pack/plugins/canvas/i18n/functions/function_help.ts +++ b/x-pack/plugins/canvas/i18n/functions/function_help.ts @@ -27,6 +27,7 @@ import { help as demodata } from './dict/demodata'; import { help as doFn } from './dict/do'; import { help as dropdownControl } from './dict/dropdown_control'; import { help as eq } from './dict/eq'; +import { help as embeddable } from './dict/embeddable'; import { help as escount } from './dict/escount'; import { help as esdocs } from './dict/esdocs'; import { help as essql } from './dict/essql'; @@ -182,6 +183,7 @@ export const getFunctionHelp = (): FunctionHelpDict => ({ do: doFn, dropdownControl, eq, + embeddable, escount, esdocs, essql, diff --git a/x-pack/plugins/canvas/kibana.json b/x-pack/plugins/canvas/kibana.json index 9c4d1b2179d82..2fd312502a3c7 100644 --- a/x-pack/plugins/canvas/kibana.json +++ b/x-pack/plugins/canvas/kibana.json @@ -25,6 +25,7 @@ "features", "inspector", "presentationUtil", + "visualizations", "uiActions", "share" ], diff --git a/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.component.tsx b/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.component.tsx index bf731876bf8c8..57f52fcf21f0f 100644 --- a/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.component.tsx +++ b/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.component.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC } from 'react'; +import React, { FC, useCallback } from 'react'; import { EuiFlyout, EuiFlyoutHeader, EuiFlyoutBody, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -27,38 +27,44 @@ const strings = { }; export interface Props { onClose: () => void; - onSelect: (id: string, embeddableType: string) => void; + onSelect: (id: string, embeddableType: string, isByValueEnabled?: boolean) => void; availableEmbeddables: string[]; + isByValueEnabled?: boolean; } -export const AddEmbeddableFlyout: FC = ({ onSelect, availableEmbeddables, onClose }) => { +export const AddEmbeddableFlyout: FC = ({ + onSelect, + availableEmbeddables, + onClose, + isByValueEnabled, +}) => { const embeddablesService = useEmbeddablesService(); const platformService = usePlatformService(); const { getEmbeddableFactories } = embeddablesService; const { getSavedObjects, getUISettings } = platformService; - const onAddPanel = (id: string, savedObjectType: string, name: string) => { - const embeddableFactories = getEmbeddableFactories(); + const onAddPanel = useCallback( + (id: string, savedObjectType: string) => { + const embeddableFactories = getEmbeddableFactories(); + // Find the embeddable type from the saved object type + const found = Array.from(embeddableFactories).find((embeddableFactory) => { + return Boolean( + embeddableFactory.savedObjectMetaData && + embeddableFactory.savedObjectMetaData.type === savedObjectType + ); + }); - // Find the embeddable type from the saved object type - const found = Array.from(embeddableFactories).find((embeddableFactory) => { - return Boolean( - embeddableFactory.savedObjectMetaData && - embeddableFactory.savedObjectMetaData.type === savedObjectType - ); - }); - - const foundEmbeddableType = found ? found.type : 'unknown'; + const foundEmbeddableType = found ? found.type : 'unknown'; - onSelect(id, foundEmbeddableType); - }; + onSelect(id, foundEmbeddableType, isByValueEnabled); + }, + [isByValueEnabled, getEmbeddableFactories, onSelect] + ); const embeddableFactories = getEmbeddableFactories(); const availableSavedObjects = Array.from(embeddableFactories) - .filter((factory) => { - return availableEmbeddables.includes(factory.type); - }) + .filter((factory) => isByValueEnabled || availableEmbeddables.includes(factory.type)) .map((factory) => factory.savedObjectMetaData) .filter>(function ( maybeSavedObjectMetaData diff --git a/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.tsx b/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.tsx index 770a4cac606b0..4dc8d963932d8 100644 --- a/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.tsx +++ b/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.tsx @@ -8,12 +8,14 @@ import React, { useMemo, useEffect, useCallback } from 'react'; import { createPortal } from 'react-dom'; import { useSelector, useDispatch } from 'react-redux'; +import { encode } from '../../../common/lib/embeddable_dataurl'; import { AddEmbeddableFlyout as Component, Props as ComponentProps } from './flyout.component'; // @ts-expect-error untyped local import { addElement } from '../../state/actions/elements'; import { getSelectedPage } from '../../state/selectors/workpad'; import { EmbeddableTypes } from '../../../canvas_plugin_src/expression_types/embeddable'; import { State } from '../../../types'; +import { useLabsService } from '../../services'; const allowedEmbeddables = { [EmbeddableTypes.map]: (id: string) => { @@ -65,6 +67,9 @@ export const AddEmbeddablePanel: React.FunctionComponent = ({ availableEmbeddables, ...restProps }) => { + const labsService = useLabsService(); + const isByValueEnabled = labsService.isProjectEnabled('labs:canvas:byValueEmbeddable'); + const dispatch = useDispatch(); const pageId = useSelector((state) => getSelectedPage(state)); @@ -74,18 +79,27 @@ export const AddEmbeddablePanel: React.FunctionComponent = ({ ); const onSelect = useCallback( - (id: string, type: string) => { + (id: string, type: string): void => { const partialElement = { expression: `markdown "Could not find embeddable for type ${type}" | render`, }; - if (allowedEmbeddables[type]) { + + // If by-value is enabled, we'll handle both by-reference and by-value embeddables + // with the new generic `embeddable` function. + // Otherwise we fallback to the embeddable type specific expressions. + if (isByValueEnabled) { + const config = encode({ savedObjectId: id }); + partialElement.expression = `embeddable config="${config}" + type="${type}" +| render`; + } else if (allowedEmbeddables[type]) { partialElement.expression = allowedEmbeddables[type](id); } addEmbeddable(pageId, partialElement); restProps.onClose(); }, - [addEmbeddable, pageId, restProps] + [addEmbeddable, pageId, restProps, isByValueEnabled] ); return ( @@ -93,6 +107,7 @@ export const AddEmbeddablePanel: React.FunctionComponent = ({ {...restProps} availableEmbeddables={availableEmbeddables || []} onSelect={onSelect} + isByValueEnabled={isByValueEnabled} /> ); }; diff --git a/x-pack/plugins/canvas/public/components/hooks/workpad/index.tsx b/x-pack/plugins/canvas/public/components/hooks/workpad/index.tsx index 50d527036560a..ffd5b095b12e5 100644 --- a/x-pack/plugins/canvas/public/components/hooks/workpad/index.tsx +++ b/x-pack/plugins/canvas/public/components/hooks/workpad/index.tsx @@ -6,3 +6,5 @@ */ export { useDownloadWorkpad, useDownloadRenderedWorkpad } from './use_download_workpad'; + +export { useIncomingEmbeddable } from './use_incoming_embeddable'; diff --git a/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts b/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts new file mode 100644 index 0000000000000..2f8e2503ea57e --- /dev/null +++ b/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts @@ -0,0 +1,86 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useEffect } from 'react'; +import { useDispatch } from 'react-redux'; +import { fromExpression } from '@kbn/interpreter/common'; +import { CANVAS_APP } from '../../../../common/lib'; +import { decode, encode } from '../../../../common/lib/embeddable_dataurl'; +import { CanvasElement, CanvasPage } from '../../../../types'; +import { useEmbeddablesService, useLabsService } from '../../../services'; +// @ts-expect-error unconverted file +import { addElement } from '../../../state/actions/elements'; +// @ts-expect-error unconverted file +import { selectToplevelNodes } from '../../../state/actions/transient'; + +import { + updateEmbeddableExpression, + fetchEmbeddableRenderable, +} from '../../../state/actions/embeddable'; +import { clearValue } from '../../../state/actions/resolved_args'; + +export const useIncomingEmbeddable = (selectedPage: CanvasPage) => { + const embeddablesService = useEmbeddablesService(); + const labsService = useLabsService(); + const dispatch = useDispatch(); + const isByValueEnabled = labsService.isProjectEnabled('labs:canvas:byValueEmbeddable'); + const stateTransferService = embeddablesService.getStateTransfer(); + + // fetch incoming embeddable from state transfer service. + const incomingEmbeddable = stateTransferService.getIncomingEmbeddablePackage(CANVAS_APP, true); + + useEffect(() => { + if (isByValueEnabled && incomingEmbeddable) { + const { embeddableId, input: incomingInput, type } = incomingEmbeddable; + + // retrieve existing element + const originalElement = selectedPage.elements.find( + ({ id }: CanvasElement) => id === embeddableId + ); + + if (originalElement) { + const originalAst = fromExpression(originalElement!.expression); + + const functionIndex = originalAst.chain.findIndex( + ({ function: fn }) => fn === 'embeddable' + ); + + const originalInput = decode( + originalAst.chain[functionIndex].arguments.config[0] as string + ); + + // clear out resolved arg for old embeddable + const argumentPath = [embeddableId, 'expressionRenderable']; + dispatch(clearValue({ path: argumentPath })); + + const updatedInput = { ...originalInput, ...incomingInput }; + + const expression = `embeddable config="${encode(updatedInput)}" + type="${type}" +| render`; + + dispatch( + updateEmbeddableExpression({ + elementId: originalElement.id, + embeddableExpression: expression, + }) + ); + + // update resolved args + dispatch(fetchEmbeddableRenderable(originalElement.id)); + + // select new embeddable element + dispatch(selectToplevelNodes([embeddableId])); + } else { + const expression = `embeddable config="${encode(incomingInput)}" + type="${type}" +| render`; + dispatch(addElement(selectedPage.id, { expression })); + } + } + }, [dispatch, selectedPage, incomingEmbeddable, isByValueEnabled]); +}; diff --git a/x-pack/plugins/canvas/public/components/workpad/workpad.tsx b/x-pack/plugins/canvas/public/components/workpad/workpad.tsx index 622c885b6ef28..7cc077203c737 100644 --- a/x-pack/plugins/canvas/public/components/workpad/workpad.tsx +++ b/x-pack/plugins/canvas/public/components/workpad/workpad.tsx @@ -27,6 +27,7 @@ import { WorkpadRoutingContext } from '../../routes/workpad'; import { usePlatformService } from '../../services'; import { Workpad as WorkpadComponent, Props } from './workpad.component'; import { State } from '../../../types'; +import { useIncomingEmbeddable } from '../hooks'; type ContainerProps = Pick; @@ -58,6 +59,9 @@ export const Workpad: FC = (props) => { }; }); + const selectedPage = propsFromState.pages[propsFromState.selectedPageNumber - 1]; + useIncomingEmbeddable(selectedPage); + const fetchAllRenderables = useCallback(() => { dispatch(fetchAllRenderablesAction()); }, [dispatch]); diff --git a/x-pack/plugins/canvas/public/components/workpad_app/workpad_app.scss b/x-pack/plugins/canvas/public/components/workpad_app/workpad_app.scss index 4acdca10d61cc..0ddd44ed8f9a8 100644 --- a/x-pack/plugins/canvas/public/components/workpad_app/workpad_app.scss +++ b/x-pack/plugins/canvas/public/components/workpad_app/workpad_app.scss @@ -31,7 +31,7 @@ $canvasLayoutFontSize: $euiFontSizeS; .canvasLayout__stageHeader { flex-grow: 0; flex-basis: auto; - padding: $euiSizeS; + padding: $euiSizeS $euiSize; font-size: $canvasLayoutFontSize; border-bottom: $euiBorderThin; background: $euiColorLightestShade; diff --git a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/__stories__/__snapshots__/editor_menu.stories.storyshot b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/__stories__/__snapshots__/editor_menu.stories.storyshot new file mode 100644 index 0000000000000..f4aab0e59e7ee --- /dev/null +++ b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/__stories__/__snapshots__/editor_menu.stories.storyshot @@ -0,0 +1,81 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots components/WorkpadHeader/EditorMenu dark mode 1`] = ` +
+
+ +
+
+`; + +exports[`Storyshots components/WorkpadHeader/EditorMenu default 1`] = ` +
+
+ +
+
+`; diff --git a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/__stories__/editor_menu.stories.tsx b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/__stories__/editor_menu.stories.tsx new file mode 100644 index 0000000000000..01048bc0af301 --- /dev/null +++ b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/__stories__/editor_menu.stories.tsx @@ -0,0 +1,107 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { storiesOf } from '@storybook/react'; +import { action } from '@storybook/addon-actions'; +import React from 'react'; +import { EmbeddableFactoryDefinition, IEmbeddable } from 'src/plugins/embeddable/public'; +import { BaseVisType, VisTypeAlias } from 'src/plugins/visualizations/public'; +import { EditorMenu } from '../editor_menu.component'; + +const testFactories: EmbeddableFactoryDefinition[] = [ + { + type: 'ml_anomaly_swimlane', + getDisplayName: () => 'Anomaly swimlane', + getIconType: () => '', + getDescription: () => 'Description for anomaly swimlane', + isEditable: () => Promise.resolve(true), + create: () => Promise.resolve({ id: 'swimlane_embeddable' } as IEmbeddable), + grouping: [ + { + id: 'ml', + getDisplayName: () => 'machine learning', + getIconType: () => 'machineLearningApp', + }, + ], + }, + { + type: 'ml_anomaly_chart', + getDisplayName: () => 'Anomaly chart', + getIconType: () => '', + getDescription: () => 'Description for anomaly chart', + isEditable: () => Promise.resolve(true), + create: () => Promise.resolve({ id: 'anomaly_chart_embeddable' } as IEmbeddable), + grouping: [ + { + id: 'ml', + getDisplayName: () => 'machine learning', + getIconType: () => 'machineLearningApp', + }, + ], + }, + { + type: 'log_stream', + getDisplayName: () => 'Log stream', + getIconType: () => '', + getDescription: () => 'Description for log stream', + isEditable: () => Promise.resolve(true), + create: () => Promise.resolve({ id: 'anomaly_chart_embeddable' } as IEmbeddable), + }, +]; + +const testVisTypes: BaseVisType[] = [ + { title: 'TSVB', icon: '', description: 'Description of TSVB', name: 'tsvb' } as BaseVisType, + { + titleInWizard: 'Custom visualization', + title: 'Vega', + icon: '', + description: 'Description of Vega', + name: 'vega', + } as BaseVisType, +]; + +const testVisTypeAliases: VisTypeAlias[] = [ + { + title: 'Lens', + aliasApp: 'lens', + aliasPath: 'path/to/lens', + icon: 'lensApp', + name: 'lens', + description: 'Description of Lens app', + stage: 'production', + }, + { + title: 'Maps', + aliasApp: 'maps', + aliasPath: 'path/to/maps', + icon: 'gisApp', + name: 'maps', + description: 'Description of Maps app', + stage: 'production', + }, +]; + +storiesOf('components/WorkpadHeader/EditorMenu', module) + .add('default', () => ( + action('createNewVisType')} + createNewEmbeddable={() => action('createNewEmbeddable')} + /> + )) + .add('dark mode', () => ( + action('createNewVisType')} + createNewEmbeddable={() => action('createNewEmbeddable')} + /> + )); diff --git a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.component.tsx b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.component.tsx new file mode 100644 index 0000000000000..e8f762f9731a1 --- /dev/null +++ b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.component.tsx @@ -0,0 +1,170 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC } from 'react'; +import { + EuiContextMenu, + EuiContextMenuPanelItemDescriptor, + EuiContextMenuItemIcon, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { EmbeddableFactoryDefinition } from '../../../../../../../src/plugins/embeddable/public'; +import { BaseVisType, VisTypeAlias } from '../../../../../../../src/plugins/visualizations/public'; +import { SolutionToolbarPopover } from '../../../../../../../src/plugins/presentation_util/public'; + +const strings = { + getEditorMenuButtonLabel: () => + i18n.translate('xpack.canvas.solutionToolbar.editorMenuButtonLabel', { + defaultMessage: 'Select type', + }), +}; + +interface FactoryGroup { + id: string; + appName: string; + icon: EuiContextMenuItemIcon; + panelId: number; + factories: EmbeddableFactoryDefinition[]; +} + +interface Props { + factories: EmbeddableFactoryDefinition[]; + isDarkThemeEnabled?: boolean; + promotedVisTypes: BaseVisType[]; + visTypeAliases: VisTypeAlias[]; + createNewVisType: (visType?: BaseVisType | VisTypeAlias) => () => void; + createNewEmbeddable: (factory: EmbeddableFactoryDefinition) => () => void; +} + +export const EditorMenu: FC = ({ + factories, + isDarkThemeEnabled, + promotedVisTypes, + visTypeAliases, + createNewVisType, + createNewEmbeddable, +}: Props) => { + const factoryGroupMap: Record = {}; + const ungroupedFactories: EmbeddableFactoryDefinition[] = []; + + let panelCount = 1; + + // Maps factories with a group to create nested context menus for each group type + // and pushes ungrouped factories into a separate array + factories.forEach((factory: EmbeddableFactoryDefinition, index) => { + const { grouping } = factory; + + if (grouping) { + grouping.forEach((group) => { + if (factoryGroupMap[group.id]) { + factoryGroupMap[group.id].factories.push(factory); + } else { + factoryGroupMap[group.id] = { + id: group.id, + appName: group.getDisplayName ? group.getDisplayName({}) : group.id, + icon: (group.getIconType ? group.getIconType({}) : 'empty') as EuiContextMenuItemIcon, + factories: [factory], + panelId: panelCount, + }; + + panelCount++; + } + }); + } else { + ungroupedFactories.push(factory); + } + }); + + const getVisTypeMenuItem = (visType: BaseVisType): EuiContextMenuPanelItemDescriptor => { + const { name, title, titleInWizard, description, icon = 'empty' } = visType; + return { + name: titleInWizard || title, + icon: icon as string, + onClick: createNewVisType(visType), + 'data-test-subj': `visType-${name}`, + toolTipContent: description, + }; + }; + + const getVisTypeAliasMenuItem = ( + visTypeAlias: VisTypeAlias + ): EuiContextMenuPanelItemDescriptor => { + const { name, title, description, icon = 'empty' } = visTypeAlias; + + return { + name: title, + icon, + onClick: createNewVisType(visTypeAlias), + 'data-test-subj': `visType-${name}`, + toolTipContent: description, + }; + }; + + const getEmbeddableFactoryMenuItem = ( + factory: EmbeddableFactoryDefinition + ): EuiContextMenuPanelItemDescriptor => { + const icon = factory?.getIconType ? factory.getIconType() : 'empty'; + + const toolTipContent = factory?.getDescription ? factory.getDescription() : undefined; + + return { + name: factory.getDisplayName(), + icon, + toolTipContent, + onClick: createNewEmbeddable(factory), + 'data-test-subj': `createNew-${factory.type}`, + }; + }; + + const editorMenuPanels = [ + { + id: 0, + items: [ + ...visTypeAliases.map(getVisTypeAliasMenuItem), + ...Object.values(factoryGroupMap).map(({ id, appName, icon, panelId }) => ({ + name: appName, + icon, + panel: panelId, + 'data-test-subj': `canvasEditorMenu-${id}Group`, + })), + ...ungroupedFactories.map(getEmbeddableFactoryMenuItem), + ...promotedVisTypes.map(getVisTypeMenuItem), + ], + }, + ...Object.values(factoryGroupMap).map( + ({ appName, panelId, factories: groupFactories }: FactoryGroup) => ({ + id: panelId, + title: appName, + items: groupFactories.map(getEmbeddableFactoryMenuItem), + }) + ), + ]; + + return ( + + {() => ( + + )} + + ); +}; diff --git a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.tsx b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.tsx new file mode 100644 index 0000000000000..dad34e6983c5d --- /dev/null +++ b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.tsx @@ -0,0 +1,147 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC, useCallback } from 'react'; +import { useLocation } from 'react-router-dom'; +import { trackCanvasUiMetric, METRIC_TYPE } from '../../../../public/lib/ui_metric'; +import { + useEmbeddablesService, + usePlatformService, + useVisualizationsService, +} from '../../../services'; +import { + BaseVisType, + VisGroups, + VisTypeAlias, +} from '../../../../../../../src/plugins/visualizations/public'; +import { + EmbeddableFactoryDefinition, + EmbeddableInput, +} from '../../../../../../../src/plugins/embeddable/public'; +import { CANVAS_APP } from '../../../../common/lib'; +import { encode } from '../../../../common/lib/embeddable_dataurl'; +import { ElementSpec } from '../../../../types'; +import { EditorMenu as Component } from './editor_menu.component'; + +interface Props { + /** + * Handler for adding a selected element to the workpad + */ + addElement: (element: Partial) => void; +} + +export const EditorMenu: FC = ({ addElement }) => { + const embeddablesService = useEmbeddablesService(); + const { pathname, search } = useLocation(); + const platformService = usePlatformService(); + const stateTransferService = embeddablesService.getStateTransfer(); + const visualizationsService = useVisualizationsService(); + const IS_DARK_THEME = platformService.getUISetting('theme:darkMode'); + + const createNewVisType = useCallback( + (visType?: BaseVisType | VisTypeAlias) => () => { + let path = ''; + let appId = ''; + + if (visType) { + if (trackCanvasUiMetric) { + trackCanvasUiMetric(METRIC_TYPE.CLICK, `${visType.name}:create`); + } + + if ('aliasPath' in visType) { + appId = visType.aliasApp; + path = visType.aliasPath; + } else { + appId = 'visualize'; + path = `#/create?type=${encodeURIComponent(visType.name)}`; + } + } else { + appId = 'visualize'; + path = '#/create?'; + } + + stateTransferService.navigateToEditor(appId, { + path, + state: { + originatingApp: CANVAS_APP, + originatingPath: `#/${pathname}${search}`, + }, + }); + }, + [stateTransferService, pathname, search] + ); + + const createNewEmbeddable = useCallback( + (factory: EmbeddableFactoryDefinition) => async () => { + if (trackCanvasUiMetric) { + trackCanvasUiMetric(METRIC_TYPE.CLICK, factory.type); + } + let embeddableInput; + if (factory.getExplicitInput) { + embeddableInput = await factory.getExplicitInput(); + } else { + const newEmbeddable = await factory.create({} as EmbeddableInput); + embeddableInput = newEmbeddable?.getInput(); + } + + if (embeddableInput) { + const config = encode(embeddableInput); + const expression = `embeddable config="${config}" + type="${factory.type}" +| render`; + + addElement({ expression }); + } + }, + [addElement] + ); + + const getVisTypesByGroup = (group: VisGroups): BaseVisType[] => + visualizationsService + .getByGroup(group) + .sort(({ name: a }: BaseVisType | VisTypeAlias, { name: b }: BaseVisType | VisTypeAlias) => { + if (a < b) { + return -1; + } + if (a > b) { + return 1; + } + return 0; + }) + .filter(({ hidden }: BaseVisType) => !hidden); + + const visTypeAliases = visualizationsService + .getAliases() + .sort(({ promotion: a = false }: VisTypeAlias, { promotion: b = false }: VisTypeAlias) => + a === b ? 0 : a ? -1 : 1 + ); + + const factories = embeddablesService + ? Array.from(embeddablesService.getEmbeddableFactories()).filter( + ({ type, isEditable, canCreateNew, isContainerType }) => + isEditable() && + !isContainerType && + canCreateNew() && + !['visualization', 'ml'].some((factoryType) => { + return type.includes(factoryType); + }) + ) + : []; + + const promotedVisTypes = getVisTypesByGroup(VisGroups.PROMOTED); + + return ( + + ); +}; diff --git a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/index.ts b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/index.ts new file mode 100644 index 0000000000000..0f903b1bbbe2e --- /dev/null +++ b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { EditorMenu } from './editor_menu'; +export { EditorMenu as EditorMenuComponent } from './editor_menu.component'; diff --git a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.component.tsx b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.component.tsx index 8ac581b0866a4..1cfab236d9a9c 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.component.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.component.tsx @@ -12,11 +12,11 @@ import { EuiContextMenu, EuiIcon, EuiContextMenuPanelItemDescriptor } from '@ela import { i18n } from '@kbn/i18n'; import { PrimaryActionPopover } from '../../../../../../../src/plugins/presentation_util/public'; import { getId } from '../../../lib/get_id'; -import { ClosePopoverFn } from '../../popover'; import { CONTEXT_MENU_TOP_BORDER_CLASSNAME } from '../../../../common/lib'; import { ElementSpec } from '../../../../types'; import { flattenPanelTree } from '../../../lib/flatten_panel_tree'; import { AssetManager } from '../../asset_manager'; +import { ClosePopoverFn } from '../../popover'; import { SavedElementsModal } from '../../saved_elements_modal'; interface CategorizedElementLists { @@ -112,7 +112,7 @@ const categorizeElementsByType = (elements: ElementSpec[]): { [key: string]: Ele return categories; }; -interface Props { +export interface Props { /** * Dictionary of elements from elements registry */ @@ -120,7 +120,7 @@ interface Props { /** * Handler for adding a selected element to the workpad */ - addElement: (element: ElementSpec) => void; + addElement: (element: Partial) => void; } export const ElementMenu: FunctionComponent = ({ elements, addElement }) => { diff --git a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/index.ts b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/index.ts index 52c8daece7690..037bb84b0cdba 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/index.ts +++ b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/index.ts @@ -5,5 +5,4 @@ * 2.0. */ -export { ElementMenu } from './element_menu'; -export { ElementMenu as ElementMenuComponent } from './element_menu.component'; +export { ElementMenu } from './element_menu.component'; diff --git a/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.component.tsx b/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.component.tsx index f031d7c263199..b84e4faf2925e 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.component.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.component.tsx @@ -27,6 +27,7 @@ import { ElementMenu } from './element_menu'; import { ShareMenu } from './share_menu'; import { ViewMenu } from './view_menu'; import { LabsControl } from './labs_control'; +import { EditorMenu } from './editor_menu'; const strings = { getFullScreenButtonAriaLabel: () => @@ -160,24 +161,22 @@ export const WorkpadHeader: FC = ({ + {isWriteable && ( + + + {{ + primaryActionButton: , + quickButtonGroup: , + addFromLibraryButton: , + extraButtons: [], + }} + + + )} - {isWriteable && ( - - - {{ - primaryActionButton: ( - - ), - quickButtonGroup: , - addFromLibraryButton: , - }} - - - )} @@ -192,6 +191,7 @@ export const WorkpadHeader: FC = ({ + diff --git a/x-pack/plugins/canvas/public/plugin.tsx b/x-pack/plugins/canvas/public/plugin.tsx index 5d1f05fdbe8bf..d2375064603c3 100644 --- a/x-pack/plugins/canvas/public/plugin.tsx +++ b/x-pack/plugins/canvas/public/plugin.tsx @@ -8,6 +8,7 @@ import { BehaviorSubject } from 'rxjs'; import type { SharePluginSetup } from 'src/plugins/share/public'; import { ChartsPluginSetup, ChartsPluginStart } from 'src/plugins/charts/public'; +import { VisualizationsStart } from 'src/plugins/visualizations/public'; import { ReportingStart } from '../../reporting/public'; import { CoreSetup, @@ -63,6 +64,7 @@ export interface CanvasStartDeps { charts: ChartsPluginStart; data: DataPublicPluginStart; presentationUtil: PresentationUtilPluginStart; + visualizations: VisualizationsStart; spaces?: SpacesPluginStart; } @@ -122,7 +124,12 @@ export class CanvasPlugin const { pluginServices } = await import('./services'); pluginServices.setRegistry( - pluginServiceRegistry.start({ coreStart, startPlugins, initContext: this.initContext }) + pluginServiceRegistry.start({ + coreStart, + startPlugins, + appUpdater: this.appUpdater, + initContext: this.initContext, + }) ); // Load application bundle diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts index 963a69a8f11f0..f117998bbd3eb 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts @@ -50,7 +50,7 @@ export const useWorkpad = ( setResolveInfo({ aliasId, outcome, id: workpadId }); // If it's an alias match, we know we are going to redirect so don't even dispatch that we got the workpad - if (outcome !== 'aliasMatch') { + if (storedWorkpad.id !== workpadId && outcome !== 'aliasMatch') { workpad.aliasId = aliasId; dispatch(setAssets(assets)); @@ -61,7 +61,7 @@ export const useWorkpad = ( setError(e as Error | string); } })(); - }, [workpadId, dispatch, setError, loadPages, workpadResolve]); + }, [workpadId, dispatch, setError, loadPages, workpadResolve, storedWorkpad.id]); useEffect(() => { // If the resolved info is not for the current workpad id, bail out diff --git a/x-pack/plugins/canvas/public/services/embeddables.ts b/x-pack/plugins/canvas/public/services/embeddables.ts index 24d7a57e086f2..26b150b7a5349 100644 --- a/x-pack/plugins/canvas/public/services/embeddables.ts +++ b/x-pack/plugins/canvas/public/services/embeddables.ts @@ -5,8 +5,12 @@ * 2.0. */ -import { EmbeddableFactory } from '../../../../../src/plugins/embeddable/public'; +import { + EmbeddableFactory, + EmbeddableStateTransfer, +} from '../../../../../src/plugins/embeddable/public'; export interface CanvasEmbeddablesService { getEmbeddableFactories: () => IterableIterator; + getStateTransfer: () => EmbeddableStateTransfer; } diff --git a/x-pack/plugins/canvas/public/services/index.ts b/x-pack/plugins/canvas/public/services/index.ts index f4292810b8089..ed55f919e4c76 100644 --- a/x-pack/plugins/canvas/public/services/index.ts +++ b/x-pack/plugins/canvas/public/services/index.ts @@ -17,6 +17,7 @@ import { CanvasNavLinkService } from './nav_link'; import { CanvasNotifyService } from './notify'; import { CanvasPlatformService } from './platform'; import { CanvasReportingService } from './reporting'; +import { CanvasVisualizationsService } from './visualizations'; import { CanvasWorkpadService } from './workpad'; export interface CanvasPluginServices { @@ -28,6 +29,7 @@ export interface CanvasPluginServices { notify: CanvasNotifyService; platform: CanvasPlatformService; reporting: CanvasReportingService; + visualizations: CanvasVisualizationsService; workpad: CanvasWorkpadService; } @@ -44,4 +46,6 @@ export const useNavLinkService = () => (() => pluginServices.getHooks().navLink. export const useNotifyService = () => (() => pluginServices.getHooks().notify.useService())(); export const usePlatformService = () => (() => pluginServices.getHooks().platform.useService())(); export const useReportingService = () => (() => pluginServices.getHooks().reporting.useService())(); +export const useVisualizationsService = () => + (() => pluginServices.getHooks().visualizations.useService())(); export const useWorkpadService = () => (() => pluginServices.getHooks().workpad.useService())(); diff --git a/x-pack/plugins/canvas/public/services/kibana/embeddables.ts b/x-pack/plugins/canvas/public/services/kibana/embeddables.ts index 054b9da7409fb..8d1a86edab3d8 100644 --- a/x-pack/plugins/canvas/public/services/kibana/embeddables.ts +++ b/x-pack/plugins/canvas/public/services/kibana/embeddables.ts @@ -16,4 +16,5 @@ export type EmbeddablesServiceFactory = KibanaPluginServiceFactory< export const embeddablesServiceFactory: EmbeddablesServiceFactory = ({ startPlugins }) => ({ getEmbeddableFactories: startPlugins.embeddable.getEmbeddableFactories, + getStateTransfer: startPlugins.embeddable.getStateTransfer, }); diff --git a/x-pack/plugins/canvas/public/services/kibana/index.ts b/x-pack/plugins/canvas/public/services/kibana/index.ts index 1eb010e8d6f9d..91767947bc0a6 100644 --- a/x-pack/plugins/canvas/public/services/kibana/index.ts +++ b/x-pack/plugins/canvas/public/services/kibana/index.ts @@ -22,6 +22,7 @@ import { navLinkServiceFactory } from './nav_link'; import { notifyServiceFactory } from './notify'; import { platformServiceFactory } from './platform'; import { reportingServiceFactory } from './reporting'; +import { visualizationsServiceFactory } from './visualizations'; import { workpadServiceFactory } from './workpad'; export { customElementServiceFactory } from './custom_element'; @@ -31,6 +32,7 @@ export { labsServiceFactory } from './labs'; export { notifyServiceFactory } from './notify'; export { platformServiceFactory } from './platform'; export { reportingServiceFactory } from './reporting'; +export { visualizationsServiceFactory } from './visualizations'; export { workpadServiceFactory } from './workpad'; export const pluginServiceProviders: PluginServiceProviders< @@ -45,6 +47,7 @@ export const pluginServiceProviders: PluginServiceProviders< notify: new PluginServiceProvider(notifyServiceFactory), platform: new PluginServiceProvider(platformServiceFactory), reporting: new PluginServiceProvider(reportingServiceFactory), + visualizations: new PluginServiceProvider(visualizationsServiceFactory), workpad: new PluginServiceProvider(workpadServiceFactory), }; diff --git a/x-pack/plugins/canvas/public/services/kibana/visualizations.ts b/x-pack/plugins/canvas/public/services/kibana/visualizations.ts new file mode 100644 index 0000000000000..e319ec1c1f427 --- /dev/null +++ b/x-pack/plugins/canvas/public/services/kibana/visualizations.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { KibanaPluginServiceFactory } from '../../../../../../src/plugins/presentation_util/public'; +import { CanvasStartDeps } from '../../plugin'; +import { CanvasVisualizationsService } from '../visualizations'; + +export type VisualizationsServiceFactory = KibanaPluginServiceFactory< + CanvasVisualizationsService, + CanvasStartDeps +>; + +export const visualizationsServiceFactory: VisualizationsServiceFactory = ({ startPlugins }) => ({ + showNewVisModal: startPlugins.visualizations.showNewVisModal, + getByGroup: startPlugins.visualizations.getByGroup, + getAliases: startPlugins.visualizations.getAliases, +}); diff --git a/x-pack/plugins/canvas/public/services/stubs/embeddables.ts b/x-pack/plugins/canvas/public/services/stubs/embeddables.ts index 173d27563e2b2..9c2cf4d0650ab 100644 --- a/x-pack/plugins/canvas/public/services/stubs/embeddables.ts +++ b/x-pack/plugins/canvas/public/services/stubs/embeddables.ts @@ -14,4 +14,5 @@ const noop = (..._args: any[]): any => {}; export const embeddablesServiceFactory: EmbeddablesServiceFactory = () => ({ getEmbeddableFactories: noop, + getStateTransfer: noop, }); diff --git a/x-pack/plugins/canvas/public/services/stubs/index.ts b/x-pack/plugins/canvas/public/services/stubs/index.ts index 06a5ff49e9c04..2216013a29c12 100644 --- a/x-pack/plugins/canvas/public/services/stubs/index.ts +++ b/x-pack/plugins/canvas/public/services/stubs/index.ts @@ -22,6 +22,7 @@ import { navLinkServiceFactory } from './nav_link'; import { notifyServiceFactory } from './notify'; import { platformServiceFactory } from './platform'; import { reportingServiceFactory } from './reporting'; +import { visualizationsServiceFactory } from './visualizations'; import { workpadServiceFactory } from './workpad'; export { customElementServiceFactory } from './custom_element'; @@ -31,6 +32,7 @@ export { navLinkServiceFactory } from './nav_link'; export { notifyServiceFactory } from './notify'; export { platformServiceFactory } from './platform'; export { reportingServiceFactory } from './reporting'; +export { visualizationsServiceFactory } from './visualizations'; export { workpadServiceFactory } from './workpad'; export const pluginServiceProviders: PluginServiceProviders = { @@ -42,6 +44,7 @@ export const pluginServiceProviders: PluginServiceProviders; + +const noop = (..._args: any[]): any => {}; + +export const visualizationsServiceFactory: VisualizationsServiceFactory = () => ({ + showNewVisModal: noop, + getByGroup: noop, + getAliases: noop, +}); diff --git a/x-pack/plugins/canvas/public/services/visualizations.ts b/x-pack/plugins/canvas/public/services/visualizations.ts new file mode 100644 index 0000000000000..c602b1dd39f3d --- /dev/null +++ b/x-pack/plugins/canvas/public/services/visualizations.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { VisualizationsStart } from '../../../../../src/plugins/visualizations/public'; + +export interface CanvasVisualizationsService { + showNewVisModal: VisualizationsStart['showNewVisModal']; + getByGroup: VisualizationsStart['getByGroup']; + getAliases: VisualizationsStart['getAliases']; +} diff --git a/x-pack/plugins/canvas/public/state/reducers/embeddable.ts b/x-pack/plugins/canvas/public/state/reducers/embeddable.ts index 4cfdc7f21945f..092d4300d86b7 100644 --- a/x-pack/plugins/canvas/public/state/reducers/embeddable.ts +++ b/x-pack/plugins/canvas/public/state/reducers/embeddable.ts @@ -40,7 +40,7 @@ export const embeddableReducer = handleActions< const element = pageWithElement.elements.find((elem) => elem.id === elementId); - if (!element) { + if (!element || element.expression === embeddableExpression) { return workpadState; } diff --git a/x-pack/plugins/canvas/server/plugin.ts b/x-pack/plugins/canvas/server/plugin.ts index 4071b891e4c3d..ebe43ba76a46a 100644 --- a/x-pack/plugins/canvas/server/plugin.ts +++ b/x-pack/plugins/canvas/server/plugin.ts @@ -14,6 +14,7 @@ import { ExpressionsServerSetup } from 'src/plugins/expressions/server'; import { BfetchServerSetup } from 'src/plugins/bfetch/server'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { HomeServerPluginSetup } from 'src/plugins/home/server'; +import { EmbeddableSetup } from 'src/plugins/embeddable/server'; import { ESSQL_SEARCH_STRATEGY } from '../common/lib/constants'; import { ReportingSetup } from '../../reporting/server'; import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server'; @@ -30,6 +31,7 @@ import { CanvasRouteHandlerContext, createWorkpadRouteContext } from './workpad_ interface PluginsSetup { expressions: ExpressionsServerSetup; + embeddable: EmbeddableSetup; features: FeaturesPluginSetup; home: HomeServerPluginSetup; bfetch: BfetchServerSetup; @@ -82,7 +84,12 @@ export class CanvasPlugin implements Plugin { const kibanaIndex = coreSetup.savedObjects.getKibanaIndex(); registerCanvasUsageCollector(plugins.usageCollection, kibanaIndex); - setupInterpreter(expressionsFork); + setupInterpreter(expressionsFork, { + embeddablePersistableStateService: { + extract: plugins.embeddable.extract, + inject: plugins.embeddable.inject, + }, + }); coreSetup.getStartServices().then(([_, depsStart]) => { const strategy = essqlSearchStrategyProvider(); diff --git a/x-pack/plugins/canvas/server/setup_interpreter.ts b/x-pack/plugins/canvas/server/setup_interpreter.ts index 2fe23eb86c086..849ad79717056 100644 --- a/x-pack/plugins/canvas/server/setup_interpreter.ts +++ b/x-pack/plugins/canvas/server/setup_interpreter.ts @@ -7,9 +7,15 @@ import { ExpressionsServerSetup } from 'src/plugins/expressions/server'; import { functions } from '../canvas_plugin_src/functions/server'; -import { functions as externalFunctions } from '../canvas_plugin_src/functions/external'; +import { + initFunctions as initExternalFunctions, + InitializeArguments, +} from '../canvas_plugin_src/functions/external'; -export function setupInterpreter(expressions: ExpressionsServerSetup) { +export function setupInterpreter( + expressions: ExpressionsServerSetup, + dependencies: InitializeArguments +) { functions.forEach((f) => expressions.registerFunction(f)); - externalFunctions.forEach((f) => expressions.registerFunction(f)); + initExternalFunctions(dependencies).forEach((f) => expressions.registerFunction(f)); } diff --git a/x-pack/plugins/canvas/types/embeddables.ts b/x-pack/plugins/canvas/types/embeddables.ts new file mode 100644 index 0000000000000..b78efece59d8f --- /dev/null +++ b/x-pack/plugins/canvas/types/embeddables.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { TimeRange } from 'src/plugins/data/public'; +import { Filter } from '@kbn/es-query'; +import { EmbeddableInput as Input } from '../../../../src/plugins/embeddable/common/'; + +export type EmbeddableInput = Input & { + timeRange?: TimeRange; + filters?: Filter[]; + savedObjectId?: string; +}; diff --git a/x-pack/plugins/canvas/types/functions.ts b/x-pack/plugins/canvas/types/functions.ts index 2569e0b10685b..c80102915ed95 100644 --- a/x-pack/plugins/canvas/types/functions.ts +++ b/x-pack/plugins/canvas/types/functions.ts @@ -10,8 +10,8 @@ import { UnwrapPromiseOrReturn } from '@kbn/utility-types'; import { functions as commonFunctions } from '../canvas_plugin_src/functions/common'; import { functions as browserFunctions } from '../canvas_plugin_src/functions/browser'; import { functions as serverFunctions } from '../canvas_plugin_src/functions/server'; -import { functions as externalFunctions } from '../canvas_plugin_src/functions/external'; -import { initFunctions } from '../public/functions'; +import { initFunctions as initExternalFunctions } from '../canvas_plugin_src/functions/external'; +import { initFunctions as initClientFunctions } from '../public/functions'; /** * A `ExpressionFunctionFactory` is a powerful type used for any function that produces @@ -90,9 +90,11 @@ export type FunctionFactory = type CommonFunction = FunctionFactory; type BrowserFunction = FunctionFactory; type ServerFunction = FunctionFactory; -type ExternalFunction = FunctionFactory; +type ExternalFunction = FunctionFactory< + ReturnType extends Array ? U : never +>; type ClientFunctions = FunctionFactory< - ReturnType extends Array ? U : never + ReturnType extends Array ? U : never >; /** diff --git a/x-pack/plugins/canvas/types/index.ts b/x-pack/plugins/canvas/types/index.ts index 09ae1510be6da..930f337292088 100644 --- a/x-pack/plugins/canvas/types/index.ts +++ b/x-pack/plugins/canvas/types/index.ts @@ -9,6 +9,7 @@ export * from '../../../../src/plugins/expressions/common'; export * from './assets'; export * from './canvas'; export * from './elements'; +export * from './embeddables'; export * from './filters'; export * from './functions'; export * from './renderers'; diff --git a/x-pack/plugins/cases/public/components/utils.test.ts b/x-pack/plugins/cases/public/components/utils.test.ts index 86d37d2e5e59e..e3cc753e75746 100644 --- a/x-pack/plugins/cases/public/components/utils.test.ts +++ b/x-pack/plugins/cases/public/components/utils.test.ts @@ -39,8 +39,49 @@ describe('Utils', () => { }); describe('isDeprecatedConnector', () => { + const connector = { + id: 'test', + actionTypeId: '.webhook', + name: 'Test', + config: { usesTableApi: false }, + secrets: {}, + isPreconfigured: false, + }; + it('returns false if the connector is not defined', () => { expect(isDeprecatedConnector()).toBe(false); }); + + it('returns false if the connector is not ITSM or SecOps', () => { + expect(isDeprecatedConnector(connector)).toBe(false); + }); + + it('returns false if the connector is .servicenow and the usesTableApi=false', () => { + expect(isDeprecatedConnector({ ...connector, actionTypeId: '.servicenow' })).toBe(false); + }); + + it('returns false if the connector is .servicenow-sir and the usesTableApi=false', () => { + expect(isDeprecatedConnector({ ...connector, actionTypeId: '.servicenow-sir' })).toBe(false); + }); + + it('returns true if the connector is .servicenow and the usesTableApi=true', () => { + expect( + isDeprecatedConnector({ + ...connector, + actionTypeId: '.servicenow', + config: { usesTableApi: true }, + }) + ).toBe(true); + }); + + it('returns true if the connector is .servicenow-sir and the usesTableApi=true', () => { + expect( + isDeprecatedConnector({ + ...connector, + actionTypeId: '.servicenow-sir', + config: { usesTableApi: true }, + }) + ).toBe(true); + }); }); }); diff --git a/x-pack/plugins/cases/public/components/utils.ts b/x-pack/plugins/cases/public/components/utils.ts index 3ac48135edae8..82d2682e65fad 100644 --- a/x-pack/plugins/cases/public/components/utils.ts +++ b/x-pack/plugins/cases/public/components/utils.ts @@ -12,11 +12,6 @@ import { StartPlugins } from '../types'; import { connectorValidator as swimlaneConnectorValidator } from './connectors/swimlane/validator'; import { connectorValidator as servicenowConnectorValidator } from './connectors/servicenow/validator'; import { CaseActionConnector } from './types'; -import { - ENABLE_NEW_SN_ITSM_CONNECTOR, - ENABLE_NEW_SN_SIR_CONNECTOR, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../actions/server/constants/connectors'; export const getConnectorById = ( id: string, @@ -83,24 +78,16 @@ export const isDeprecatedConnector = (connector?: CaseActionConnector): boolean return false; } - if (!ENABLE_NEW_SN_ITSM_CONNECTOR && connector.actionTypeId === '.servicenow') { - return true; + if (connector.actionTypeId === '.servicenow' || connector.actionTypeId === '.servicenow-sir') { + /** + * Connector's prior to the Elastic ServiceNow application + * use the Table API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_TableAPI) + * Connectors after the Elastic ServiceNow application use the + * Import Set API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_ImportSetAPI) + * A ServiceNow connector is considered deprecated if it uses the Table API. + */ + return !!connector.config.usesTableApi; } - if (!ENABLE_NEW_SN_SIR_CONNECTOR && connector.actionTypeId === '.servicenow-sir') { - return true; - } - - /** - * Connector's prior to the Elastic ServiceNow application - * use the Table API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_TableAPI) - * Connectors after the Elastic ServiceNow application use the - * Import Set API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_ImportSetAPI) - * A ServiceNow connector is considered deprecated if it uses the Table API. - * - * All other connectors do not have the usesTableApi config property - * so the function will always return false for them. - */ - - return !!connector.config.usesTableApi; + return false; }; diff --git a/x-pack/plugins/data_visualizer/kibana.json b/x-pack/plugins/data_visualizer/kibana.json index e63a6b4fa2100..81fc0a2fdfe02 100644 --- a/x-pack/plugins/data_visualizer/kibana.json +++ b/x-pack/plugins/data_visualizer/kibana.json @@ -25,7 +25,8 @@ "kibanaReact", "maps", "esUiShared", - "fieldFormats" + "fieldFormats", + "charts" ], "extraPublicDirs": [ "common" diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/document_count_content/document_count_chart/document_count_chart.tsx b/x-pack/plugins/data_visualizer/public/application/common/components/document_count_content/document_count_chart/document_count_chart.tsx index 6459fc4006cea..13b68d3b192cc 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/document_count_content/document_count_chart/document_count_chart.tsx +++ b/x-pack/plugins/data_visualizer/public/application/common/components/document_count_content/document_count_chart/document_count_chart.tsx @@ -6,16 +6,13 @@ */ import React, { FC, useCallback, useMemo } from 'react'; - import { i18n } from '@kbn/i18n'; - import { Axis, BarSeries, BrushEndListener, Chart, ElementClickListener, - niceTimeFormatter, Position, ScaleType, Settings, @@ -23,7 +20,9 @@ import { XYBrushEvent, } from '@elastic/charts'; import moment from 'moment'; +import { IUiSettingsClient } from 'kibana/public'; import { useDataVisualizerKibana } from '../../../../kibana_context'; +import { MULTILAYER_TIME_AXIS_STYLE } from '../../../../../../../../../src/plugins/charts/common'; export interface DocumentCountChartPoint { time: number | string; @@ -40,6 +39,16 @@ interface Props { const SPEC_ID = 'document_count'; +function getTimezone(uiSettings: IUiSettingsClient) { + if (uiSettings.isDefault('dateFormat:tz')) { + const detectedTimezone = moment.tz.guess(); + if (detectedTimezone) return detectedTimezone; + else return moment().format('Z'); + } else { + return uiSettings.get('dateFormat:tz', 'Browser'); + } +} + export const DocumentCountChart: FC = ({ width, chartPoints, @@ -48,9 +57,12 @@ export const DocumentCountChart: FC = ({ interval, }) => { const { - services: { data }, + services: { data, uiSettings, fieldFormats }, } = useDataVisualizerKibana(); + const xAxisFormatter = fieldFormats.deserialize({ id: 'date' }); + const useLegacyTimeAxis = uiSettings.get('visualization:useLegacyTimeAxis', false); + const seriesName = i18n.translate( 'xpack.dataVisualizer.dataGrid.field.documentCountChart.seriesLabel', { @@ -63,8 +75,6 @@ export const DocumentCountChart: FC = ({ max: timeRangeLatest, }; - const dateFormatter = niceTimeFormatter([timeRangeEarliest, timeRangeLatest]); - const adjustedChartPoints = useMemo(() => { // Display empty chart when no data in range if (chartPoints.length < 1) return [{ time: timeRangeEarliest, value: 0 }]; @@ -110,6 +120,8 @@ export const DocumentCountChart: FC = ({ timefilterUpdateHandler(range); }; + const timeZone = getTimezone(uiSettings); + return (
= ({ id="bottom" position={Position.Bottom} showOverlappingTicks={true} - tickFormat={dateFormatter} + tickFormat={(value) => xAxisFormatter.convert(value)} + timeAxisLayerCount={useLegacyTimeAxis ? 0 : 2} + style={useLegacyTimeAxis ? {} : MULTILAYER_TIME_AXIS_STYLE} /> = ({ xAccessor="time" yAccessors={['value']} data={adjustedChartPoints} + timeZone={timeZone} />
diff --git a/x-pack/plugins/data_visualizer/public/plugin.ts b/x-pack/plugins/data_visualizer/public/plugin.ts index df1a5ea406d76..dd1d2acccf8cd 100644 --- a/x-pack/plugins/data_visualizer/public/plugin.ts +++ b/x-pack/plugins/data_visualizer/public/plugin.ts @@ -22,6 +22,7 @@ import { getFileDataVisualizerComponent, getIndexDataVisualizerComponent } from import { getMaxBytesFormatted } from './application/common/util/get_max_bytes'; import { registerHomeAddData, registerHomeFeatureCatalogue } from './register_home'; import { registerEmbeddables } from './application/index_data_visualizer/embeddables'; +import { FieldFormatsStart } from '../../../../src/plugins/field_formats/public'; export interface DataVisualizerSetupDependencies { home?: HomePublicPluginSetup; @@ -36,6 +37,7 @@ export interface DataVisualizerStartDependencies { share: SharePluginStart; lens?: LensPublicStart; indexPatternFieldEditor?: IndexPatternFieldEditorStart; + fieldFormats: FieldFormatsStart; } export type DataVisualizerPluginSetup = ReturnType; diff --git a/x-pack/plugins/enterprise_search/common/__mocks__/initial_app_data.ts b/x-pack/plugins/enterprise_search/common/__mocks__/initial_app_data.ts index 5d4844c3296d7..aa3020a9577f9 100644 --- a/x-pack/plugins/enterprise_search/common/__mocks__/initial_app_data.ts +++ b/x-pack/plugins/enterprise_search/common/__mocks__/initial_app_data.ts @@ -7,7 +7,6 @@ export const DEFAULT_INITIAL_APP_DATA = { readOnlyMode: false, - ilmEnabled: true, searchOAuth: { clientId: 'someUID', redirectUrl: 'http://localhost:3002/ws/search_callback', diff --git a/x-pack/plugins/enterprise_search/common/types/index.ts b/x-pack/plugins/enterprise_search/common/types/index.ts index b0b9eb6274875..8addf17f97476 100644 --- a/x-pack/plugins/enterprise_search/common/types/index.ts +++ b/x-pack/plugins/enterprise_search/common/types/index.ts @@ -16,7 +16,6 @@ import { export interface InitialAppData { readOnlyMode?: boolean; - ilmEnabled?: boolean; searchOAuth?: SearchOAuth; configuredLimits?: ConfiguredLimits; access?: ProductAccess; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts index f69e3492d26eb..09b4292a29008 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts @@ -25,7 +25,6 @@ describe('AppLogic', () => { mount({}, DEFAULT_INITIAL_APP_DATA); expect(AppLogic.values).toEqual({ - ilmEnabled: true, configuredLimits: { engine: { maxDocumentByteSize: 102400, diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.ts index 90b37e6a4d4ee..96bf4c062dbaf 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.ts @@ -16,7 +16,6 @@ import { ConfiguredLimits, Account, Role } from './types'; import { getRoleAbilities } from './utils/role'; interface AppValues { - ilmEnabled: boolean; configuredLimits: ConfiguredLimits; account: Account; myRole: Role; @@ -41,7 +40,6 @@ export const AppLogic = kea = ({ type, disabledAt }) => { ); }; -export const ILMDisabled: React.FC = ({ type }) => ( - -); - export const CustomPolicy: React.FC = ({ type }) => ( { const analytics = LogRetentionOptions.Analytics; const api = LogRetentionOptions.API; - const setLogRetention = (logRetention: object, ilmEnabled: boolean = true) => { + const setLogRetention = (logRetention: object) => { const logRetentionSettings = { disabledAt: null, enabled: true, @@ -30,7 +30,6 @@ describe('LogRetentionMessage', () => { }; setMockValues({ - ilmEnabled, logRetention: { [LogRetentionOptions.API]: logRetentionSettings, [LogRetentionOptions.Analytics]: logRetentionSettings, @@ -155,22 +154,4 @@ describe('LogRetentionMessage', () => { }); }); }); - - describe('when ILM is disabled entirely', () => { - describe('an ILM disabled message renders', () => { - beforeEach(() => { - setLogRetention({}, false); - }); - - it('for analytics', () => { - const wrapper = mountWithIntl(); - expect(wrapper.text()).toEqual("App Search isn't managing analytics log retention."); - }); - - it('for api', () => { - const wrapper = mountWithIntl(); - expect(wrapper.text()).toEqual("App Search isn't managing API log retention."); - }); - }); - }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/log_retention_message.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/log_retention_message.tsx index 7d34a2567ba14..c461de72edb88 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/log_retention_message.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/log_retention_message.tsx @@ -9,18 +9,15 @@ import React from 'react'; import { useValues } from 'kea'; -import { AppLogic } from '../../../app_logic'; import { LogRetentionLogic } from '../log_retention_logic'; import { LogRetentionOptions } from '../types'; -import { NoLogging, ILMDisabled, CustomPolicy, DefaultPolicy } from './constants'; +import { NoLogging, CustomPolicy, DefaultPolicy } from './constants'; interface Props { type: LogRetentionOptions; } export const LogRetentionMessage: React.FC = ({ type }) => { - const { ilmEnabled } = useValues(AppLogic); - const { logRetention } = useValues(LogRetentionLogic); if (!logRetention) return null; @@ -30,9 +27,6 @@ export const LogRetentionMessage: React.FC = ({ type }) => { if (!logRetentionSettings.enabled) { return ; } - if (!ilmEnabled) { - return ; - } if (!logRetentionSettings.retentionPolicy?.isDefault) { return ; } else { diff --git a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts index 3f2a038d8bff3..ba600de298976 100644 --- a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts @@ -46,7 +46,6 @@ describe('callEnterpriseSearchConfigAPI', () => { settings: { external_url: 'http://some.vanity.url/', read_only_mode: false, - ilm_enabled: true, is_federated_auth: false, search_oauth: { client_id: 'someUID', @@ -139,7 +138,6 @@ describe('callEnterpriseSearchConfigAPI', () => { }, publicUrl: undefined, readOnlyMode: false, - ilmEnabled: false, searchOAuth: { clientId: undefined, redirectUrl: undefined, diff --git a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.ts b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.ts index 146b06e4d9a4c..d652d56c28efe 100644 --- a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.ts +++ b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.ts @@ -74,7 +74,6 @@ export const callEnterpriseSearchConfigAPI = async ({ }, publicUrl: stripTrailingSlash(data?.settings?.external_url), readOnlyMode: !!data?.settings?.read_only_mode, - ilmEnabled: !!data?.settings?.ilm_enabled, searchOAuth: { clientId: data?.settings?.search_oauth?.client_id, redirectUrl: data?.settings?.search_oauth?.redirect_url, diff --git a/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts b/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts index ed5f8e07098d4..b050a7c798a0b 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts @@ -67,6 +67,12 @@ export type DeletePackagePoliciesResponse = Array<{ export interface UpgradePackagePolicyBaseResponse { name?: string; + + // Support generic errors + statusCode?: number; + body?: { + message: string; + }; } export interface UpgradePackagePolicyDryRunResponseItem extends UpgradePackagePolicyBaseResponse { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx index 1092b7ac89c07..bf4b1eb00abe0 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx @@ -368,7 +368,7 @@ const AgentPolicySelectionStep = ({ diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.tsx index 91bd29d14d0b3..3dc704399c914 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.tsx @@ -235,7 +235,7 @@ function MissingIntegrationContent({

@@ -245,11 +245,11 @@ function MissingIntegrationContent({ /> ), - discussForumLink: ( + forumLink: ( ), diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx index c8c6f49356810..b6f236852f940 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx @@ -370,12 +370,12 @@ export function Detail() { content: missingSecurityConfiguration ? ( ) : ( ), } diff --git a/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts index 58463bfa5569d..f61890f852798 100644 --- a/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts @@ -192,6 +192,8 @@ export const deletePackagePolicyHandler: RequestHandler< } }; +// TODO: Separate the upgrade and dry-run processes into separate endpoints, and address +// duplicate logic in error handling as part of https://github.com/elastic/kibana/issues/63123 export const upgradePackagePolicyHandler: RequestHandler< unknown, unknown, @@ -212,6 +214,16 @@ export const upgradePackagePolicyHandler: RequestHandler< ); body.push(result); } + + const firstFatalError = body.find((item) => item.statusCode && item.statusCode !== 200); + + if (firstFatalError) { + return response.customError({ + statusCode: firstFatalError.statusCode!, + body: { message: firstFatalError.body!.message }, + }); + } + return response.ok({ body, }); @@ -222,6 +234,15 @@ export const upgradePackagePolicyHandler: RequestHandler< request.body.packagePolicyIds, { user } ); + + const firstFatalError = body.find((item) => item.statusCode && item.statusCode !== 200); + + if (firstFatalError) { + return response.customError({ + statusCode: firstFatalError.statusCode!, + body: { message: firstFatalError.body!.message }, + }); + } return response.ok({ body, }); diff --git a/x-pack/plugins/fleet/server/services/managed_package_policies.ts b/x-pack/plugins/fleet/server/services/managed_package_policies.ts index 306725ae01953..e78bc096b8711 100644 --- a/x-pack/plugins/fleet/server/services/managed_package_policies.ts +++ b/x-pack/plugins/fleet/server/services/managed_package_policies.ts @@ -72,7 +72,10 @@ export const upgradeManagedPackagePolicies = async ( ); if (dryRunResults.hasErrors) { - const errors = dryRunResults.diff?.[1].errors; + const errors = dryRunResults.diff + ? dryRunResults.diff?.[1].errors + : dryRunResults.body?.message; + appContextService .getLogger() .error( diff --git a/x-pack/plugins/fleet/server/services/package_policy.ts b/x-pack/plugins/fleet/server/services/package_policy.ts index 985351c3e981b..c4ef15f4e7ed9 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.ts @@ -620,13 +620,6 @@ class PackagePolicyService { success: true, }); } catch (error) { - // We only want to specifically handle validation errors for the new package policy. If a more severe or - // general error is thrown elsewhere during the upgrade process, we want to surface that directly in - // order to preserve any status code mappings, etc that might be included w/ the particular error type - if (!(error instanceof PackagePolicyValidationError)) { - throw error; - } - result.push({ id, success: false, @@ -704,10 +697,6 @@ class PackagePolicyService { hasErrors, }; } catch (error) { - if (!(error instanceof PackagePolicyValidationError)) { - throw error; - } - return { hasErrors: true, ...ingestErrorToResponseOptions(error), diff --git a/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx index 4d57674c94dad..095ce9f78cdff 100644 --- a/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx +++ b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx @@ -261,6 +261,11 @@ export const Expressions: React.FC = (props) => { [alertParams.groupBy] ); + const disableNoData = useMemo( + () => alertParams.criteria?.every((c) => c.aggType === Aggregators.COUNT), + [alertParams.criteria] + ); + // Test to see if any of the group fields in groupBy are already filtered down to a single // group by the filterQuery. If this is the case, then a groupBy is unnecessary, as it would only // ever produce one group instance @@ -358,6 +363,7 @@ export const Expressions: React.FC = (props) => { > @@ -365,10 +371,13 @@ export const Expressions: React.FC = (props) => { defaultMessage: "Alert me if there's no data", })}{' '} @@ -488,16 +497,19 @@ export const Expressions: React.FC = (props) => { defaultMessage: 'Alert me if a group stops reporting data', })}{' '} } - disabled={!hasGroupBy} + disabled={disableNoData || !hasGroupBy} checked={Boolean(hasGroupBy && alertParams.alertOnGroupDisappear)} onChange={(e) => setAlertParams('alertOnGroupDisappear', e.target.checked)} /> @@ -506,6 +518,13 @@ export const Expressions: React.FC = (props) => { ); }; +const docCountNoDataDisabledHelpText = i18n.translate( + 'xpack.infra.metrics.alertFlyout.docCountNoDataDisabledHelpText', + { + defaultMessage: '[This setting is not applicable to the Document Count aggregator.]', + } +); + // required for dynamic import // eslint-disable-next-line import/no-default-export export default Expressions; diff --git a/x-pack/plugins/lens/common/expressions/expression_types/index.ts b/x-pack/plugins/lens/common/expressions/expression_types/index.ts new file mode 100644 index 0000000000000..78821e429fa8f --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/expression_types/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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { lensMultitable } from './lens_multitable'; +export type { LensMultitableExpressionTypeDefinition } from './lens_multitable'; diff --git a/x-pack/plugins/lens/common/expressions/expression_types/lens_multitable.ts b/x-pack/plugins/lens/common/expressions/expression_types/lens_multitable.ts new file mode 100644 index 0000000000000..8817f9315e182 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/expression_types/lens_multitable.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ExpressionTypeDefinition } from '../../../../../../src/plugins/expressions/common'; +import { LensMultiTable } from '../../types'; + +const name = 'lens_multitable'; + +type Input = LensMultiTable; + +export type LensMultitableExpressionTypeDefinition = ExpressionTypeDefinition< + typeof name, + Input, + Input +>; + +export const lensMultitable: LensMultitableExpressionTypeDefinition = { + name, + to: { + datatable: (input: Input) => { + return Object.values(input.tables)[0]; + }, + }, +}; diff --git a/x-pack/plugins/lens/common/expressions/index.ts b/x-pack/plugins/lens/common/expressions/index.ts index 70a85f85938e4..344d22de6461b 100644 --- a/x-pack/plugins/lens/common/expressions/index.ts +++ b/x-pack/plugins/lens/common/expressions/index.ts @@ -15,3 +15,5 @@ export * from './heatmap_chart'; export * from './metric_chart'; export * from './pie_chart'; export * from './xy_chart'; + +export * from './expression_types'; diff --git a/x-pack/plugins/lens/public/expressions.ts b/x-pack/plugins/lens/public/expressions.ts index 27f3179a2d0c8..9d972d8ed6941 100644 --- a/x-pack/plugins/lens/public/expressions.ts +++ b/x-pack/plugins/lens/public/expressions.ts @@ -33,12 +33,15 @@ import { formatColumn } from '../common/expressions/format_column'; import { counterRate } from '../common/expressions/counter_rate'; import { getTimeScale } from '../common/expressions/time_scale/time_scale'; import { metricChart } from '../common/expressions/metric_chart/metric_chart'; +import { lensMultitable } from '../common/expressions'; export const setupExpressions = ( expressions: ExpressionsSetup, formatFactory: Parameters[0], getTimeZone: Parameters[0] -) => +) => { + [lensMultitable].forEach((expressionType) => expressions.registerType(expressionType)); + [ pie, xyChart, @@ -62,3 +65,4 @@ export const setupExpressions = ( getDatatable(formatFactory), getTimeScale(getTimeZone), ].forEach((expressionFn) => expressions.registerFunction(expressionFn)); +}; diff --git a/x-pack/plugins/lens/server/expressions/expressions.ts b/x-pack/plugins/lens/server/expressions/expressions.ts index 882b8b938717b..a04ad27d1a276 100644 --- a/x-pack/plugins/lens/server/expressions/expressions.ts +++ b/x-pack/plugins/lens/server/expressions/expressions.ts @@ -22,6 +22,7 @@ import { axisTitlesVisibilityConfig, getTimeScale, getDatatable, + lensMultitable, } from '../../common/expressions'; import { getFormatFactory, getTimeZoneFactory } from './utils'; @@ -32,6 +33,8 @@ export const setupExpressions = ( core: CoreSetup, expressions: ExpressionsServerSetup ) => { + [lensMultitable].forEach((expressionType) => expressions.registerType(expressionType)); + [ pie, xyChart, diff --git a/x-pack/plugins/maps/common/migrations/add_field_meta_options.js b/x-pack/plugins/maps/common/migrations/add_field_meta_options.js index 8143c05913f7b..33a98c7dbf33c 100644 --- a/x-pack/plugins/maps/common/migrations/add_field_meta_options.js +++ b/x-pack/plugins/maps/common/migrations/add_field_meta_options.js @@ -18,7 +18,13 @@ export function addFieldMetaOptions({ attributes }) { return attributes; } - const layerList = JSON.parse(attributes.layerListJSON); + let layerList = []; + try { + layerList = JSON.parse(attributes.layerListJSON); + } catch (e) { + throw new Error('Unable to parse attribute layerListJSON'); + } + layerList.forEach((layerDescriptor) => { if (isVectorLayer(layerDescriptor) && _.has(layerDescriptor, 'style.properties')) { Object.values(layerDescriptor.style.properties).forEach((stylePropertyDescriptor) => { diff --git a/x-pack/plugins/maps/common/migrations/add_type_to_termjoin.ts b/x-pack/plugins/maps/common/migrations/add_type_to_termjoin.ts index e46bf6a1a6e7f..b43b8979094bb 100644 --- a/x-pack/plugins/maps/common/migrations/add_type_to_termjoin.ts +++ b/x-pack/plugins/maps/common/migrations/add_type_to_termjoin.ts @@ -21,7 +21,12 @@ export function addTypeToTermJoin({ return attributes; } - const layerList: LayerDescriptor[] = JSON.parse(attributes.layerListJSON); + let layerList: LayerDescriptor[] = []; + try { + layerList = JSON.parse(attributes.layerListJSON); + } catch (e) { + throw new Error('Unable to parse attribute layerListJSON'); + } layerList.forEach((layer: LayerDescriptor) => { if (!('joins' in layer)) { diff --git a/x-pack/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 index 4e52e88bcc1cd..2945b9efed958 100644 --- a/x-pack/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 @@ -23,7 +23,13 @@ export function emsRasterTileToEmsVectorTile({ attributes }) { return attributes; } - const layerList = JSON.parse(attributes.layerListJSON); + let layerList = []; + try { + layerList = JSON.parse(attributes.layerListJSON); + } catch (e) { + throw new Error('Unable to parse attribute layerListJSON'); + } + layerList.forEach((layer) => { if (isTileLayer(layer) && isEmsTileSource(layer)) { // Just need to switch layer type to migrate TILE layer to VECTOR_TILE layer diff --git a/x-pack/plugins/maps/common/migrations/join_agg_key.ts b/x-pack/plugins/maps/common/migrations/join_agg_key.ts index e3e5a2fac34f4..726855783be63 100644 --- a/x-pack/plugins/maps/common/migrations/join_agg_key.ts +++ b/x-pack/plugins/maps/common/migrations/join_agg_key.ts @@ -62,7 +62,13 @@ export function migrateJoinAggKey({ return attributes; } - const layerList: LayerDescriptor[] = JSON.parse(attributes.layerListJSON); + let layerList = []; + try { + layerList = JSON.parse(attributes.layerListJSON); + } catch (e) { + throw new Error('Unable to parse attribute layerListJSON'); + } + layerList.forEach((layerDescriptor: LayerDescriptor) => { if ( layerDescriptor.type === LAYER_TYPE.VECTOR || diff --git a/x-pack/plugins/maps/common/migrations/migrate_symbol_style_descriptor.js b/x-pack/plugins/maps/common/migrations/migrate_symbol_style_descriptor.js index 3d06c60d23df7..6dab8595663ed 100644 --- a/x-pack/plugins/maps/common/migrations/migrate_symbol_style_descriptor.js +++ b/x-pack/plugins/maps/common/migrations/migrate_symbol_style_descriptor.js @@ -18,7 +18,13 @@ export function migrateSymbolStyleDescriptor({ attributes }) { return attributes; } - const layerList = JSON.parse(attributes.layerListJSON); + let layerList = []; + try { + layerList = JSON.parse(attributes.layerListJSON); + } catch (e) { + throw new Error('Unable to parse attribute layerListJSON'); + } + layerList.forEach((layerDescriptor) => { if (!isVectorLayer(layerDescriptor) || !_.has(layerDescriptor, 'style.properties')) { return; diff --git a/x-pack/plugins/maps/common/migrations/move_apply_global_query.js b/x-pack/plugins/maps/common/migrations/move_apply_global_query.js index 2d485400db9ca..b0c7d2031ffa7 100644 --- a/x-pack/plugins/maps/common/migrations/move_apply_global_query.js +++ b/x-pack/plugins/maps/common/migrations/move_apply_global_query.js @@ -22,7 +22,13 @@ export function moveApplyGlobalQueryToSources({ attributes }) { return attributes; } - const layerList = JSON.parse(attributes.layerListJSON); + let layerList = []; + try { + layerList = JSON.parse(attributes.layerListJSON); + } catch (e) { + throw new Error('Unable to parse attribute layerListJSON'); + } + layerList.forEach((layerDescriptor) => { const applyGlobalQuery = _.get(layerDescriptor, 'applyGlobalQuery', true); delete layerDescriptor.applyGlobalQuery; diff --git a/x-pack/plugins/maps/common/migrations/move_attribution.ts b/x-pack/plugins/maps/common/migrations/move_attribution.ts index 74258e815439e..6ab5fb93ca981 100644 --- a/x-pack/plugins/maps/common/migrations/move_attribution.ts +++ b/x-pack/plugins/maps/common/migrations/move_attribution.ts @@ -18,7 +18,12 @@ export function moveAttribution({ return attributes; } - const layerList: LayerDescriptor[] = JSON.parse(attributes.layerListJSON); + let layerList: LayerDescriptor[] = []; + try { + layerList = JSON.parse(attributes.layerListJSON); + } catch (e) { + throw new Error('Unable to parse attribute layerListJSON'); + } layerList.forEach((layer: LayerDescriptor) => { const sourceDescriptor = layer.sourceDescriptor as { diff --git a/x-pack/plugins/maps/common/migrations/references.ts b/x-pack/plugins/maps/common/migrations/references.ts index 41d9dc063fe47..1ced7e06c59cc 100644 --- a/x-pack/plugins/maps/common/migrations/references.ts +++ b/x-pack/plugins/maps/common/migrations/references.ts @@ -29,7 +29,13 @@ export function extractReferences({ const extractedReferences: SavedObjectReference[] = []; - const layerList: LayerDescriptor[] = JSON.parse(attributes.layerListJSON); + let layerList: LayerDescriptor[] = []; + try { + layerList = JSON.parse(attributes.layerListJSON); + } catch (e) { + throw new Error('Unable to parse attribute layerListJSON'); + } + layerList.forEach((layer, layerIndex) => { // Extract index-pattern references from source descriptor if (layer.sourceDescriptor && 'indexPatternId' in layer.sourceDescriptor) { @@ -92,7 +98,13 @@ export function injectReferences({ return { attributes }; } - const layerList: LayerDescriptor[] = JSON.parse(attributes.layerListJSON); + let layerList: LayerDescriptor[] = []; + try { + layerList = JSON.parse(attributes.layerListJSON); + } catch (e) { + throw new Error('Unable to parse attribute layerListJSON'); + } + layerList.forEach((layer) => { // Inject index-pattern references into source descriptor if (layer.sourceDescriptor && 'indexPatternRefName' in layer.sourceDescriptor) { diff --git a/x-pack/plugins/maps/common/migrations/scaling_type.ts b/x-pack/plugins/maps/common/migrations/scaling_type.ts index 1744b3627b1d6..5106784a16d0a 100644 --- a/x-pack/plugins/maps/common/migrations/scaling_type.ts +++ b/x-pack/plugins/maps/common/migrations/scaling_type.ts @@ -24,7 +24,13 @@ export function migrateUseTopHitsToScalingType({ return attributes; } - const layerList: LayerDescriptor[] = JSON.parse(attributes.layerListJSON); + let layerList: LayerDescriptor[] = []; + try { + layerList = JSON.parse(attributes.layerListJSON); + } catch (e) { + throw new Error('Unable to parse attribute layerListJSON'); + } + layerList.forEach((layerDescriptor: LayerDescriptor) => { if (isEsDocumentSource(layerDescriptor)) { const sourceDescriptor = layerDescriptor.sourceDescriptor as ESSearchSourceDescriptor; diff --git a/x-pack/plugins/maps/common/migrations/set_default_auto_fit_to_bounds.ts b/x-pack/plugins/maps/common/migrations/set_default_auto_fit_to_bounds.ts index 36fd3cf8da7e2..af86b62165683 100644 --- a/x-pack/plugins/maps/common/migrations/set_default_auto_fit_to_bounds.ts +++ b/x-pack/plugins/maps/common/migrations/set_default_auto_fit_to_bounds.ts @@ -16,10 +16,14 @@ export function setDefaultAutoFitToBounds({ return attributes; } - // MapState type is defined in public, no need to bring all of that to common for this migration - const mapState: { settings?: { autoFitToDataBounds: boolean } } = JSON.parse( - attributes.mapStateJSON - ); + // MapState type is defined in public, no need to pull type definition into common for this migration + let mapState: { settings?: { autoFitToDataBounds: boolean } } = {}; + try { + mapState = JSON.parse(attributes.mapStateJSON); + } catch (e) { + throw new Error('Unable to parse attribute mapStateJSON'); + } + if ('settings' in mapState) { mapState.settings!.autoFitToDataBounds = false; } else { diff --git a/x-pack/plugins/maps/common/migrations/set_ems_tms_default_modes.ts b/x-pack/plugins/maps/common/migrations/set_ems_tms_default_modes.ts index 94dbd8741add7..aab0d6b345428 100644 --- a/x-pack/plugins/maps/common/migrations/set_ems_tms_default_modes.ts +++ b/x-pack/plugins/maps/common/migrations/set_ems_tms_default_modes.ts @@ -22,7 +22,13 @@ export function setEmsTmsDefaultModes({ return attributes; } - const layerList: LayerDescriptor[] = JSON.parse(attributes.layerListJSON); + let layerList: LayerDescriptor[] = []; + try { + layerList = JSON.parse(attributes.layerListJSON); + } catch (e) { + throw new Error('Unable to parse attribute layerListJSON'); + } + layerList.forEach((layerDescriptor: LayerDescriptor) => { if (layerDescriptor.sourceDescriptor?.type === SOURCE_TYPES.EMS_TMS) { const sourceDescriptor = layerDescriptor.sourceDescriptor as EMSTMSSourceDescriptor; diff --git a/x-pack/plugins/maps/common/migrations/top_hits_time_to_sort.js b/x-pack/plugins/maps/common/migrations/top_hits_time_to_sort.js index ea7ea6cf91c66..fa5b5111ff797 100644 --- a/x-pack/plugins/maps/common/migrations/top_hits_time_to_sort.js +++ b/x-pack/plugins/maps/common/migrations/top_hits_time_to_sort.js @@ -19,7 +19,13 @@ export function topHitsTimeToSort({ attributes }) { return attributes; } - const layerList = JSON.parse(attributes.layerListJSON); + let layerList = []; + try { + layerList = JSON.parse(attributes.layerListJSON); + } catch (e) { + throw new Error('Unable to parse attribute layerListJSON'); + } + layerList.forEach((layerDescriptor) => { if (isEsDocumentSource(layerDescriptor)) { if (_.has(layerDescriptor, 'sourceDescriptor.topHitsTimeField')) { diff --git a/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx b/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx index 8fc2d97c4862a..3825c92f31371 100644 --- a/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx +++ b/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx @@ -40,7 +40,6 @@ import { MapContainer } from '../../../connected_components/map_container'; import { getIndexPatternsFromIds } from '../../../index_pattern_util'; import { getTopNavConfig } from '../top_nav_config'; import { goToSpecifiedPath } from '../../../render_app'; -import { MapSavedObjectAttributes } from '../../../../common/map_saved_object_type'; import { getEditPath, getFullPath, APP_ID } from '../../../../common/constants'; import { getMapEmbeddableDisplayName } from '../../../../common/i18n_getters'; import { @@ -52,11 +51,7 @@ import { unsavedChangesWarning, } from '../saved_map'; import { waitUntilTimeLayersLoad$ } from './wait_until_time_layers_load'; - -interface MapRefreshConfig { - isPaused: boolean; - interval: number; -} +import { RefreshConfig as MapRefreshConfig, SerializedMapState } from '../saved_map'; export interface Props { savedMap: SavedMap; @@ -248,20 +243,14 @@ export class MapApp extends React.Component { updateGlobalState(updatedGlobalState, !this.state.initialized); }; - _initMapAndLayerSettings(mapSavedObjectAttributes: MapSavedObjectAttributes) { + _initMapAndLayerSettings(serializedMapState?: SerializedMapState) { const globalState: MapsGlobalState = getGlobalState(); - let savedObjectFilters = []; - if (mapSavedObjectAttributes.mapStateJSON) { - const mapState = JSON.parse(mapSavedObjectAttributes.mapStateJSON); - if (mapState.filters) { - savedObjectFilters = mapState.filters; - } - } + const savedObjectFilters = serializedMapState?.filters ? serializedMapState.filters : []; const appFilters = this._appStateManager.getFilters() || []; const query = getInitialQuery({ - mapStateJSON: mapSavedObjectAttributes.mapStateJSON, + serializedMapState, appState: this._appStateManager.getAppState(), }); if (query) { @@ -272,14 +261,14 @@ export class MapApp extends React.Component { filters: [..._.get(globalState, 'filters', []), ...appFilters, ...savedObjectFilters], query, time: getInitialTimeFilters({ - mapStateJSON: mapSavedObjectAttributes.mapStateJSON, + serializedMapState, globalState, }), }); this._onRefreshConfigChange( getInitialRefreshConfig({ - mapStateJSON: mapSavedObjectAttributes.mapStateJSON, + serializedMapState, globalState, }) ); @@ -371,7 +360,16 @@ export class MapApp extends React.Component { ); } - this._initMapAndLayerSettings(this.props.savedMap.getAttributes()); + let serializedMapState: SerializedMapState | undefined; + try { + const attributes = this.props.savedMap.getAttributes(); + if (attributes.mapStateJSON) { + serializedMapState = JSON.parse(attributes.mapStateJSON); + } + } catch (e) { + // ignore malformed mapStateJSON, not a critical error for viewing map - map will just use defaults + } + this._initMapAndLayerSettings(serializedMapState); this.setState({ initialized: true }); } diff --git a/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_query.ts b/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_query.ts index 276e89f78ebac..1a57c09672c04 100644 --- a/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_query.ts +++ b/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_query.ts @@ -7,23 +7,21 @@ import { getData } from '../../../kibana_services'; import { MapsAppState } from '../url_state'; +import { SerializedMapState } from './types'; export function getInitialQuery({ - mapStateJSON, + serializedMapState, appState = {}, }: { - mapStateJSON?: string; + serializedMapState?: SerializedMapState; appState: MapsAppState; }) { if (appState.query) { return appState.query; } - if (mapStateJSON) { - const mapState = JSON.parse(mapStateJSON); - if (mapState.query) { - return mapState.query; - } + if (serializedMapState?.query) { + return serializedMapState.query; } return getData().query.queryString.getDefaultQuery(); diff --git a/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_refresh_config.ts b/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_refresh_config.ts index b343323cdf7ab..ad5a56dcd4c26 100644 --- a/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_refresh_config.ts +++ b/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_refresh_config.ts @@ -8,21 +8,19 @@ import { QueryState } from 'src/plugins/data/public'; import { getUiSettings } from '../../../kibana_services'; import { UI_SETTINGS } from '../../../../../../../src/plugins/data/public'; +import { SerializedMapState } from './types'; export function getInitialRefreshConfig({ - mapStateJSON, + serializedMapState, globalState = {}, }: { - mapStateJSON?: string; + serializedMapState?: SerializedMapState; globalState: QueryState; }) { const uiSettings = getUiSettings(); - if (mapStateJSON) { - const mapState = JSON.parse(mapStateJSON); - if (mapState.refreshConfig) { - return mapState.refreshConfig; - } + if (serializedMapState?.refreshConfig) { + return serializedMapState.refreshConfig; } const defaultRefreshConfig = uiSettings.get(UI_SETTINGS.TIMEPICKER_REFRESH_INTERVAL_DEFAULTS); diff --git a/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_time_filters.ts b/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_time_filters.ts index 80c5d70ebacf2..9cb67cefde547 100644 --- a/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_time_filters.ts +++ b/x-pack/plugins/maps/public/routes/map_page/saved_map/get_initial_time_filters.ts @@ -7,19 +7,17 @@ import { QueryState } from 'src/plugins/data/public'; import { getUiSettings } from '../../../kibana_services'; +import { SerializedMapState } from './types'; export function getInitialTimeFilters({ - mapStateJSON, + serializedMapState, globalState, }: { - mapStateJSON?: string; + serializedMapState?: SerializedMapState; globalState: QueryState; }) { - if (mapStateJSON) { - const mapState = JSON.parse(mapStateJSON); - if (mapState.timeFilters) { - return mapState.timeFilters; - } + if (serializedMapState?.timeFilters) { + return serializedMapState.timeFilters; } const defaultTime = getUiSettings().get('timepicker:timeDefaults'); diff --git a/x-pack/plugins/maps/public/routes/map_page/saved_map/index.ts b/x-pack/plugins/maps/public/routes/map_page/saved_map/index.ts index 549c9949b9027..a3e8ef96160bb 100644 --- a/x-pack/plugins/maps/public/routes/map_page/saved_map/index.ts +++ b/x-pack/plugins/maps/public/routes/map_page/saved_map/index.ts @@ -5,6 +5,7 @@ * 2.0. */ +export type { RefreshConfig, SerializedMapState, SerializedUiState } from './types'; export { SavedMap } from './saved_map'; export { getInitialLayersFromUrlParam } from './get_initial_layers_from_url_param'; export { getInitialQuery } from './get_initial_query'; diff --git a/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts b/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts index 004b88a242623..3cff8d9713830 100644 --- a/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts +++ b/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts @@ -47,6 +47,7 @@ import { getBreadcrumbs } from './get_breadcrumbs'; import { DEFAULT_IS_LAYER_TOC_OPEN } from '../../../reducers/ui'; import { createBasemapLayerDescriptor } from '../../../classes/layers/create_basemap_layer_descriptor'; import { whenLicenseInitialized } from '../../../licensed_features'; +import { SerializedMapState, SerializedUiState } from './types'; export class SavedMap { private _attributes: MapSavedObjectAttributes | null = null; @@ -113,9 +114,13 @@ export class SavedMap { if (this._mapEmbeddableInput && this._mapEmbeddableInput.mapSettings !== undefined) { this._store.dispatch(setMapSettings(this._mapEmbeddableInput.mapSettings)); } else if (this._attributes?.mapStateJSON) { - const mapState = JSON.parse(this._attributes.mapStateJSON); - if (mapState.settings) { - this._store.dispatch(setMapSettings(mapState.settings)); + try { + const mapState = JSON.parse(this._attributes.mapStateJSON) as SerializedMapState; + if (mapState.settings) { + this._store.dispatch(setMapSettings(mapState.settings)); + } + } catch (e) { + // ignore malformed mapStateJSON, not a critical error for viewing map - map will just use defaults } } @@ -123,20 +128,28 @@ export class SavedMap { if (this._mapEmbeddableInput && this._mapEmbeddableInput.isLayerTOCOpen !== undefined) { isLayerTOCOpen = this._mapEmbeddableInput.isLayerTOCOpen; } else if (this._attributes?.uiStateJSON) { - const uiState = JSON.parse(this._attributes.uiStateJSON); - if ('isLayerTOCOpen' in uiState) { - isLayerTOCOpen = uiState.isLayerTOCOpen; + try { + const uiState = JSON.parse(this._attributes.uiStateJSON) as SerializedUiState; + if ('isLayerTOCOpen' in uiState) { + isLayerTOCOpen = uiState.isLayerTOCOpen; + } + } catch (e) { + // ignore malformed uiStateJSON, not a critical error for viewing map - map will just use defaults } } this._store.dispatch(setIsLayerTOCOpen(isLayerTOCOpen)); - let openTOCDetails = []; + let openTOCDetails: string[] = []; if (this._mapEmbeddableInput && this._mapEmbeddableInput.openTOCDetails !== undefined) { openTOCDetails = this._mapEmbeddableInput.openTOCDetails; } else if (this._attributes?.uiStateJSON) { - const uiState = JSON.parse(this._attributes.uiStateJSON); - if ('openTOCDetails' in uiState) { - openTOCDetails = uiState.openTOCDetails; + try { + const uiState = JSON.parse(this._attributes.uiStateJSON) as SerializedUiState; + if ('openTOCDetails' in uiState) { + openTOCDetails = uiState.openTOCDetails; + } + } catch (e) { + // ignore malformed uiStateJSON, not a critical error for viewing map - map will just use defaults } } this._store.dispatch(setOpenTOCDetails(openTOCDetails)); @@ -150,19 +163,27 @@ export class SavedMap { }) ); } else if (this._attributes?.mapStateJSON) { - const mapState = JSON.parse(this._attributes.mapStateJSON); - this._store.dispatch( - setGotoWithCenter({ - lat: mapState.center.lat, - lon: mapState.center.lon, - zoom: mapState.zoom, - }) - ); + try { + const mapState = JSON.parse(this._attributes.mapStateJSON) as SerializedMapState; + this._store.dispatch( + setGotoWithCenter({ + lat: mapState.center.lat, + lon: mapState.center.lon, + zoom: mapState.zoom, + }) + ); + } catch (e) { + // ignore malformed mapStateJSON, not a critical error for viewing map - map will just use defaults + } } let layerList: LayerDescriptor[] = []; if (this._attributes.layerListJSON) { - layerList = JSON.parse(this._attributes.layerListJSON); + try { + layerList = JSON.parse(this._attributes.layerListJSON) as LayerDescriptor[]; + } catch (e) { + throw new Error('Malformed saved object: unable to parse layerListJSON'); + } } else { const basemapLayerDescriptor = createBasemapLayerDescriptor(); if (basemapLayerDescriptor) { @@ -413,11 +434,11 @@ export class SavedMap { query: getQuery(state), filters: getFilters(state), settings: getMapSettings(state), - }); + } as SerializedMapState); this._attributes!.uiStateJSON = JSON.stringify({ isLayerTOCOpen: getIsLayerTOCOpen(state), openTOCDetails: getOpenTOCDetails(state), - }); + } as SerializedUiState); } } diff --git a/x-pack/plugins/maps/public/routes/map_page/saved_map/types.ts b/x-pack/plugins/maps/public/routes/map_page/saved_map/types.ts new file mode 100644 index 0000000000000..808007c075533 --- /dev/null +++ b/x-pack/plugins/maps/public/routes/map_page/saved_map/types.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Query } from 'src/plugins/data/common'; +import { Filter, TimeRange } from '../../../../../../../src/plugins/data/public'; +import { MapCenter } from '../../../../common/descriptor_types'; +import { MapSettings } from '../../../reducers/map'; + +export interface RefreshConfig { + isPaused: boolean; + interval: number; +} + +// parsed contents of mapStateJSON +export interface SerializedMapState { + zoom: number; + center: MapCenter; + timeFilters?: TimeRange; + refreshConfig: RefreshConfig; + query?: Query; + filters: Filter[]; + settings: MapSettings; +} + +// parsed contents of uiStateJSON +export interface SerializedUiState { + isLayerTOCOpen: boolean; + openTOCDetails: string[]; +} diff --git a/x-pack/plugins/maps/server/embeddable_migrations.ts b/x-pack/plugins/maps/server/embeddable_migrations.ts index a49e776d4fe02..962f5c4fb0d7a 100644 --- a/x-pack/plugins/maps/server/embeddable_migrations.ts +++ b/x-pack/plugins/maps/server/embeddable_migrations.ts @@ -19,15 +19,27 @@ import { setEmsTmsDefaultModes } from '../common/migrations/set_ems_tms_default_ */ export const embeddableMigrations = { '7.14.0': (state: SerializableRecord) => { - return { - ...state, - attributes: moveAttribution(state as { attributes: MapSavedObjectAttributes }), - } as SerializableRecord; + try { + return { + ...state, + attributes: moveAttribution(state as { attributes: MapSavedObjectAttributes }), + } as SerializableRecord; + } catch (e) { + // Do not fail migration for invalid layerListJSON + // Maps application can display invalid layerListJSON error when saved object is viewed + return state; + } }, '8.0.0': (state: SerializableRecord) => { - return { - ...state, - attributes: setEmsTmsDefaultModes(state as { attributes: MapSavedObjectAttributes }), - } as SerializableRecord; + try { + return { + ...state, + attributes: setEmsTmsDefaultModes(state as { attributes: MapSavedObjectAttributes }), + } as SerializableRecord; + } catch (e) { + // Do not fail migration for invalid layerListJSON + // Maps application can display invalid layerListJSON error when saved object is viewed + return state; + } }, }; diff --git a/x-pack/plugins/maps/server/saved_objects/saved_object_migrations.js b/x-pack/plugins/maps/server/saved_objects/saved_object_migrations.js index 5fc15e8929714..6d23246860423 100644 --- a/x-pack/plugins/maps/server/saved_objects/saved_object_migrations.js +++ b/x-pack/plugins/maps/server/saved_objects/saved_object_migrations.js @@ -19,6 +19,14 @@ import { addTypeToTermJoin } from '../../common/migrations/add_type_to_termjoin' import { moveAttribution } from '../../common/migrations/move_attribution'; import { setEmsTmsDefaultModes } from '../../common/migrations/set_ems_tms_default_modes'; +function logMigrationWarning(context, errorMsg, doc) { + context.log.warning( + `map migration failed (${context.migrationVersion}). ${errorMsg}. attributes: ${JSON.stringify( + doc + )}` + ); +} + /* * Embeddables such as Maps, Lens, and Visualize can be embedded by value or by reference on a dashboard. * To ensure that any migrations (>7.12) are run correctly in both cases, @@ -27,95 +35,150 @@ import { setEmsTmsDefaultModes } from '../../common/migrations/set_ems_tms_defau * This is the saved object migration registry. */ export const savedObjectMigrations = { - '7.2.0': (doc) => { - const { attributes, references } = extractReferences(doc); + '7.2.0': (doc, context) => { + try { + const { attributes, references } = extractReferences(doc); - return { - ...doc, - attributes, - references, - }; + return { + ...doc, + attributes, + references, + }; + } catch (e) { + logMigrationWarning(context, e.message, doc); + return doc; + } }, - '7.4.0': (doc) => { - const attributes = emsRasterTileToEmsVectorTile(doc); + '7.4.0': (doc, context) => { + try { + const attributes = emsRasterTileToEmsVectorTile(doc); - return { - ...doc, - attributes, - }; + return { + ...doc, + attributes, + }; + } catch (e) { + logMigrationWarning(context, e.message, doc); + return doc; + } }, - '7.5.0': (doc) => { - const attributes = topHitsTimeToSort(doc); + '7.5.0': (doc, context) => { + try { + const attributes = topHitsTimeToSort(doc); - return { - ...doc, - attributes, - }; + return { + ...doc, + attributes, + }; + } catch (e) { + logMigrationWarning(context, e.message, doc); + return doc; + } }, - '7.6.0': (doc) => { - const attributesPhase1 = moveApplyGlobalQueryToSources(doc); - const attributesPhase2 = addFieldMetaOptions({ attributes: attributesPhase1 }); + '7.6.0': (doc, context) => { + try { + const attributesPhase1 = moveApplyGlobalQueryToSources(doc); + const attributesPhase2 = addFieldMetaOptions({ attributes: attributesPhase1 }); - return { - ...doc, - attributes: attributesPhase2, - }; + return { + ...doc, + attributes: attributesPhase2, + }; + } catch (e) { + logMigrationWarning(context, e.message, doc); + return doc; + } }, - '7.7.0': (doc) => { - const attributesPhase1 = migrateSymbolStyleDescriptor(doc); - const attributesPhase2 = migrateUseTopHitsToScalingType({ attributes: attributesPhase1 }); + '7.7.0': (doc, context) => { + try { + const attributesPhase1 = migrateSymbolStyleDescriptor(doc); + const attributesPhase2 = migrateUseTopHitsToScalingType({ attributes: attributesPhase1 }); - return { - ...doc, - attributes: attributesPhase2, - }; + return { + ...doc, + attributes: attributesPhase2, + }; + } catch (e) { + logMigrationWarning(context, e.message, doc); + return doc; + } }, - '7.8.0': (doc) => { - const attributes = migrateJoinAggKey(doc); + '7.8.0': (doc, context) => { + try { + const attributes = migrateJoinAggKey(doc); - return { - ...doc, - attributes, - }; + return { + ...doc, + attributes, + }; + } catch (e) { + logMigrationWarning(context, e.message, doc); + return doc; + } }, - '7.9.0': (doc) => { - const attributes = removeBoundsFromSavedObject(doc); + '7.9.0': (doc, context) => { + try { + const attributes = removeBoundsFromSavedObject(doc); - return { - ...doc, - attributes, - }; + return { + ...doc, + attributes, + }; + } catch (e) { + logMigrationWarning(context, e.message, doc); + return doc; + } }, - '7.10.0': (doc) => { - const attributes = setDefaultAutoFitToBounds(doc); + '7.10.0': (doc, context) => { + try { + const attributes = setDefaultAutoFitToBounds(doc); - return { - ...doc, - attributes, - }; + return { + ...doc, + attributes, + }; + } catch (e) { + logMigrationWarning(context, e.message, doc); + return doc; + } }, - '7.12.0': (doc) => { - const attributes = addTypeToTermJoin(doc); + '7.12.0': (doc, context) => { + try { + const attributes = addTypeToTermJoin(doc); - return { - ...doc, - attributes, - }; + return { + ...doc, + attributes, + }; + } catch (e) { + logMigrationWarning(context, e.message, doc); + return doc; + } }, - '7.14.0': (doc) => { - const attributes = moveAttribution(doc); + '7.14.0': (doc, context) => { + try { + const attributes = moveAttribution(doc); - return { - ...doc, - attributes, - }; + return { + ...doc, + attributes, + }; + } catch (e) { + logMigrationWarning(context, e.message, doc); + return doc; + } }, - '8.0.0': (doc) => { - const attributes = setEmsTmsDefaultModes(doc); + '8.0.0': (doc, context) => { + try { + const attributes = setEmsTmsDefaultModes(doc); - return { - ...doc, - attributes, - }; + return { + ...doc, + attributes, + }; + } catch (e) { + logMigrationWarning(context, e.message, doc); + return doc; + } }, }; diff --git a/x-pack/plugins/ml/common/constants/trained_models.ts b/x-pack/plugins/ml/common/constants/trained_models.ts new file mode 100644 index 0000000000000..019189ea13c05 --- /dev/null +++ b/x-pack/plugins/ml/common/constants/trained_models.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const DEPLOYMENT_STATE = { + STARTED: 'started', + STARTING: 'starting', + STOPPING: 'stopping', +} as const; + +export type DeploymentState = typeof DEPLOYMENT_STATE[keyof typeof DEPLOYMENT_STATE]; diff --git a/x-pack/plugins/ml/common/types/locator.ts b/x-pack/plugins/ml/common/types/locator.ts index 79db780b791fd..e13dbf7c5b271 100644 --- a/x-pack/plugins/ml/common/types/locator.ts +++ b/x-pack/plugins/ml/common/types/locator.ts @@ -188,6 +188,10 @@ export interface TrainedModelsQueryState { modelId?: string; } +export interface TrainedModelsNodesQueryState { + nodeId?: string; +} + export type DataFrameAnalyticsUrlState = MLPageState< | typeof ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE | typeof ML_PAGES.DATA_FRAME_ANALYTICS_MAP @@ -255,7 +259,8 @@ export type MlLocatorState = | CalendarEditUrlState | FilterEditUrlState | MlGenericUrlState - | TrainedModelsUrlState; + | TrainedModelsUrlState + | TrainedModelsNodesUrlState; export type MlLocatorParams = MlLocatorState & SerializableRecord; @@ -265,3 +270,8 @@ export type TrainedModelsUrlState = MLPageState< typeof ML_PAGES.TRAINED_MODELS_MANAGE, TrainedModelsQueryState | undefined >; + +export type TrainedModelsNodesUrlState = MLPageState< + typeof ML_PAGES.TRAINED_MODELS_NODES, + TrainedModelsNodesQueryState | undefined +>; diff --git a/x-pack/plugins/ml/common/types/trained_models.ts b/x-pack/plugins/ml/common/types/trained_models.ts index 5ad1d85d9feb9..89b8a50846cb3 100644 --- a/x-pack/plugins/ml/common/types/trained_models.ts +++ b/x-pack/plugins/ml/common/types/trained_models.ts @@ -5,9 +5,10 @@ * 2.0. */ -import { DataFrameAnalyticsConfig } from './data_frame_analytics'; -import { FeatureImportanceBaseline, TotalFeatureImportance } from './feature_importance'; -import { XOR } from './common'; +import type { DataFrameAnalyticsConfig } from './data_frame_analytics'; +import type { FeatureImportanceBaseline, TotalFeatureImportance } from './feature_importance'; +import type { XOR } from './common'; +import type { DeploymentState } from '../constants/trained_models'; export interface IngestStats { count: number; @@ -17,8 +18,8 @@ export interface IngestStats { } export interface TrainedModelStat { - model_id: string; - pipeline_count: number; + model_id?: string; + pipeline_count?: number; inference_stats?: { failure_count: number; inference_count: number; @@ -100,6 +101,9 @@ export interface TrainedModelConfigResponse { tags: string[]; version: string; inference_config?: Record; + /** + * Associated pipelines. Extends response from the ES endpoint. + */ pipelines?: Record | null; } @@ -125,7 +129,7 @@ export interface TrainedModelDeploymentStatsResponse { model_size_bytes: number; inference_threads: number; model_threads: number; - state: string; + state: DeploymentState; allocation_status: { target_allocation_count: number; state: string; allocation_count: number }; nodes: Array<{ node: Record< @@ -150,24 +154,35 @@ export interface TrainedModelDeploymentStatsResponse { }>; } +export interface AllocatedModel { + inference_threads: number; + allocation_status: { + target_allocation_count: number; + state: string; + allocation_count: number; + }; + model_id: string; + state: string; + model_threads: number; + model_size_bytes: number; + node: { + average_inference_time_ms: number; + inference_count: number; + routing_state: { + routing_state: string; + reason?: string; + }; + last_access?: number; + }; +} + export interface NodeDeploymentStatsResponse { id: string; name: string; transport_address: string; attributes: Record; roles: string[]; - allocated_models: Array<{ - inference_threads: number; - allocation_status: { - target_allocation_count: number; - state: string; - allocation_count: number; - }; - model_id: string; - state: string; - model_threads: number; - model_size_bytes: number; - }>; + allocated_models: AllocatedModel[]; memory_overview: { machine_memory: { /** Total machine memory in bytes */ diff --git a/x-pack/plugins/ml/public/application/components/navigation_menu/main_tabs.tsx b/x-pack/plugins/ml/public/application/components/navigation_menu/main_tabs.tsx index 78fc10e77b2da..614db1ba0df9d 100644 --- a/x-pack/plugins/ml/public/application/components/navigation_menu/main_tabs.tsx +++ b/x-pack/plugins/ml/public/application/components/navigation_menu/main_tabs.tsx @@ -7,7 +7,7 @@ import React, { FC, useState, useEffect } from 'react'; -import { EuiPageHeader, EuiBetaBadge } from '@elastic/eui'; +import { EuiPageHeader } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { TabId } from './navigation_menu'; import { useMlKibana, useMlLocator, useNavigateToPath } from '../../contexts/kibana'; @@ -57,20 +57,6 @@ function getTabs(disableLinks: boolean): Tab[] { defaultMessage: 'Model Management', }), disabled: disableLinks, - betaTag: ( - - ), }, { id: 'datavisualizer', @@ -201,7 +187,6 @@ export const MainTabs: FC = ({ tabId, disableLinks }) => { }, 'data-test-subj': testSubject + (id === selectedTabId ? ' selected' : ''), isSelected: id === selectedTabId, - append: tab.betaTag, }; })} /> diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/use_field_formatter.ts b/x-pack/plugins/ml/public/application/contexts/kibana/use_field_formatter.ts index 508ce66f40f47..d089a43b3fb39 100644 --- a/x-pack/plugins/ml/public/application/contexts/kibana/use_field_formatter.ts +++ b/x-pack/plugins/ml/public/application/contexts/kibana/use_field_formatter.ts @@ -6,12 +6,26 @@ */ import { useMlKibana } from './kibana_context'; +import { FIELD_FORMAT_IDS } from '../../../../../../../src/plugins/field_formats/common'; -export function useFieldFormatter(fieldType: 'bytes') { +/** + * Set of reasonable defaults for formatters for the ML app. + */ +const defaultParam = { + [FIELD_FORMAT_IDS.DURATION]: { + inputFormat: 'milliseconds', + outputFormat: 'humanizePrecise', + }, +} as Record; + +export function useFieldFormatter(fieldType: FIELD_FORMAT_IDS) { const { services: { fieldFormats }, } = useMlKibana(); - const fieldFormatter = fieldFormats.deserialize({ id: fieldType }); + const fieldFormatter = fieldFormats.deserialize({ + id: fieldType, + params: defaultParam[fieldType], + }); return fieldFormatter.convert.bind(fieldFormatter); } diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/expanded_row.tsx b/x-pack/plugins/ml/public/application/trained_models/models_management/expanded_row.tsx index 4b342fe02b4d5..6dd7db1dbb7b6 100644 --- a/x-pack/plugins/ml/public/application/trained_models/models_management/expanded_row.tsx +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/expanded_row.tsx @@ -5,7 +5,8 @@ * 2.0. */ -import React, { FC, Fragment } from 'react'; +import React, { FC, Fragment, useEffect, useState } from 'react'; +import { omit } from 'lodash'; import { EuiBadge, EuiButtonEmpty, @@ -15,6 +16,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, + EuiListGroup, EuiNotificationBadge, EuiPanel, EuiSpacer, @@ -25,11 +27,13 @@ import { } from '@elastic/eui'; import { EuiDescriptionListProps } from '@elastic/eui/src/components/description_list/description_list'; import { FormattedMessage } from '@kbn/i18n/react'; +import type { EuiListGroupItemProps } from '@elastic/eui/src/components/list_group/list_group_item'; import { ModelItemFull } from './models_list'; -import { useMlKibana } from '../../contexts/kibana'; +import { useMlKibana, useMlLocator } from '../../contexts/kibana'; import { timeFormatter } from '../../../../common/util/date_utils'; import { isDefined } from '../../../../common/types/guards'; import { isPopulatedObject } from '../../../../common'; +import { ML_PAGES } from '../../../../common/constants/locator'; interface ExpandedRowProps { item: ModelItemFull; @@ -85,6 +89,12 @@ export function formatToListItems( } export const ExpandedRow: FC = ({ item }) => { + const mlLocator = useMlLocator(); + + const [deploymentStatsItems, setDeploymentStats] = useState( + [] + ); + const { inference_config: inferenceConfig, stats, @@ -119,6 +129,42 @@ export const ExpandedRow: FC = ({ item }) => { services: { share }, } = useMlKibana(); + useEffect( + function updateDeploymentState() { + (async function () { + const { nodes, ...deploymentStats } = stats.deployment_stats ?? {}; + + if (!isPopulatedObject(deploymentStats)) return; + + const result = formatToListItems(deploymentStats)!; + + const items: EuiListGroupItemProps[] = await Promise.all( + nodes!.map(async (v) => { + const nodeObject = Object.values(v.node)[0]; + const href = await mlLocator!.getUrl({ + page: ML_PAGES.TRAINED_MODELS_NODES, + pageState: { + nodeId: nodeObject.name, + }, + }); + return { + label: nodeObject.name, + href, + }; + }) + ); + + result.push({ + title: 'nodes', + description: , + }); + + setDeploymentStats(result); + })(); + }, + [stats.deployment_stats] + ); + const tabs = [ { id: 'details', @@ -234,164 +280,168 @@ export const ExpandedRow: FC = ({ item }) => { }, ] : []), - { - id: 'stats', - name: ( - - ), - content: ( - <> - - {stats.deployment_stats && ( - <> - - -

- -
- + ...(isPopulatedObject(omit(stats, 'pipeline_count')) + ? [ + { + id: 'stats', + name: ( + + ), + content: ( + <> - - - - - )} - - {stats.inference_stats && ( - - - -
- -
-
- - -
-
- )} - {stats.ingest?.total && ( - - - -
- -
-
- - - - {stats.ingest?.pipelines && ( - <> - + {!!deploymentStatsItems?.length ? ( + <> +
- - {Object.entries(stats.ingest.pipelines).map( - ([pipelineName, { processors, ...pipelineStats }], i) => { - return ( - - - - - -
- {i + 1}. {pipelineName} -
-
-
-
- - - -
- - - - -
- -
-
- - <> - {processors.map((processor) => { - const name = Object.keys(processor)[0]; - const { stats: processorStats } = processor[name]; - return ( - - - - - -
{name}
-
-
-
- - - -
- - -
- ); - })} - -
- ); - } - )} - + + +
+ + + ) : null} + + {stats.inference_stats && ( + + + +
+ +
+
+ + +
+
)} -
-
- )} -
- - ), - }, + {stats.ingest?.total && ( + + + +
+ +
+
+ + + + {stats.ingest?.pipelines && ( + <> + + +
+ +
+
+ + {Object.entries(stats.ingest.pipelines).map( + ([pipelineName, { processors, ...pipelineStats }], i) => { + return ( + + + + + +
+ {i + 1}. {pipelineName} +
+
+
+
+ + + +
+ + + + +
+ +
+
+ + <> + {processors.map((processor) => { + const name = Object.keys(processor)[0]; + const { stats: processorStats } = processor[name]; + return ( + + + + + +
{name}
+
+
+
+ + + +
+ + +
+ ); + })} + +
+ ); + } + )} + + )} +
+
+ )} + + + ), + }, + ] + : []), ...(pipelines && Object.keys(pipelines).length > 0 ? [ { diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/models_list.tsx b/x-pack/plugins/ml/public/application/trained_models/models_management/models_list.tsx index 16b9aa760f535..9c3cc1f93a9cd 100644 --- a/x-pack/plugins/ml/public/application/trained_models/models_management/models_list.tsx +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/models_list.tsx @@ -5,19 +5,19 @@ * 2.0. */ -import React, { FC, useState, useCallback, useMemo } from 'react'; -import { groupBy } from 'lodash'; +import React, { FC, useCallback, useEffect, useMemo, useState } from 'react'; +import { omit } from 'lodash'; import { - EuiInMemoryTable, + EuiBadge, + EuiButton, + EuiButtonIcon, EuiFlexGroup, EuiFlexItem, - EuiTitle, - EuiButton, + EuiInMemoryTable, + EuiSearchBarProps, EuiSpacer, - EuiButtonIcon, - EuiBadge, + EuiTitle, SearchFilterConfig, - EuiSearchBarProps, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -48,9 +48,12 @@ import { ListingPageUrlState } from '../../../../common/types/common'; import { usePageUrlState } from '../../util/url_state'; import { ExpandedRow } from './expanded_row'; import { isPopulatedObject } from '../../../../common'; -import { timeFormatter } from '../../../../common/util/date_utils'; import { useTableSettings } from '../../data_frame_analytics/pages/analytics_management/components/analytics_list/use_table_settings'; import { useToastNotificationService } from '../../services/toast_notification_service'; +import { useFieldFormatter } from '../../contexts/kibana/use_field_formatter'; +import { FIELD_FORMAT_IDS } from '../../../../../../../src/plugins/field_formats/common'; +import { useRefresh } from '../../routing/use_refresh'; +import { DEPLOYMENT_STATE } from '../../../../common/constants/trained_models'; type Stats = Omit; @@ -82,11 +85,15 @@ export const ModelsList: FC = () => { } = useMlKibana(); const urlLocator = useMlLocator()!; + const dateFormatter = useFieldFormatter(FIELD_FORMAT_IDS.DATE); + const [pageState, updatePageState] = usePageUrlState( ML_PAGES.TRAINED_MODELS_MANAGE, getDefaultModelsListState() ); + const refresh = useRefresh(); + const searchQueryText = pageState.queryText ?? ''; const canDeleteDataFrameAnalytics = capabilities.ml.canDeleteDataFrameAnalytics as boolean; @@ -121,7 +128,7 @@ export const ModelsList: FC = () => { size: 1000, }); - const newItems = []; + const newItems: ModelItem[] = []; const expandedItemsToRefresh = []; for (const model of response) { @@ -145,6 +152,11 @@ export const ModelsList: FC = () => { } } + // Need to fetch state for 3rd party models to enable/disable actions + await fetchAndPopulateDeploymentStats( + newItems.filter((v) => v.model_type.includes('pytorch')) + ); + setItems(newItems); if (expandedItemsToRefresh.length > 0) { @@ -175,6 +187,13 @@ export const ModelsList: FC = () => { onRefresh: fetchModelsData, }); + useEffect( + function updateOnTimerRefresh() { + fetchModelsData(); + }, + [refresh] + ); + const modelsStats: ModelsBarStats = useMemo(() => { return { total: { @@ -191,8 +210,6 @@ export const ModelsList: FC = () => { * Fetches models stats and update the original object */ const fetchModelsStats = useCallback(async (models: ModelItem[]) => { - const { true: pytorchModels } = groupBy(models, (m) => m.model_type === 'pytorch'); - try { if (models) { const { trained_model_stats: modelsStatsResponse } = @@ -200,19 +217,12 @@ export const ModelsList: FC = () => { for (const { model_id: id, ...stats } of modelsStatsResponse) { const model = models.find((m) => m.model_id === id); - model!.stats = stats; - } - } - - if (pytorchModels) { - const { deployment_stats: deploymentStatsResponse } = - await trainedModelsApiService.getTrainedModelDeploymentStats( - pytorchModels.map((m) => m.model_id) - ); - - for (const { model_id: id, ...stats } of deploymentStatsResponse) { - const model = models.find((m) => m.model_id === id); - model!.stats!.deployment_stats = stats; + if (model) { + model.stats = { + ...(model.stats ?? {}), + ...stats, + }; + } } } @@ -227,6 +237,39 @@ export const ModelsList: FC = () => { } }, []); + /** + * Updates model items with deployment stats; + * + * We have to fetch all deployment stats on each update, + * because for stopped models the API returns 404 response. + */ + const fetchAndPopulateDeploymentStats = useCallback(async (modelItems: ModelItem[]) => { + try { + const { deployment_stats: deploymentStats } = + await trainedModelsApiService.getTrainedModelDeploymentStats('*'); + + for (const deploymentStat of deploymentStats) { + const deployedModel = modelItems.find( + (model) => model.model_id === deploymentStat.model_id + ); + + if (deployedModel) { + deployedModel.stats = { + ...(deployedModel.stats ?? {}), + deployment_stats: omit(deploymentStat, 'model_id'), + }; + } + } + } catch (error) { + displayErrorToast( + error, + i18n.translate('xpack.ml.trainedModels.modelsList.fetchDeploymentStatsErrorMessage', { + defaultMessage: 'Fetch deployment stats failed', + }) + ); + } + }, []); + /** * Unique inference types from models */ @@ -361,12 +404,19 @@ export const ModelsList: FC = () => { description: i18n.translate('xpack.ml.inference.modelsList.startModelAllocationActionLabel', { defaultMessage: 'Start allocation', }), - icon: 'download', + icon: 'play', type: 'icon', isPrimary: true, + enabled: (item) => { + const { state } = item.stats?.deployment_stats ?? {}; + return ( + !isLoading && state !== DEPLOYMENT_STATE.STARTED && state !== DEPLOYMENT_STATE.STARTING + ); + }, available: (item) => item.model_type === 'pytorch', onClick: async (item) => { try { + setIsLoading(true); await trainedModelsApiService.startModelAllocation(item.model_id); displaySuccessToast( i18n.translate('xpack.ml.trainedModels.modelsList.startSuccess', { @@ -376,6 +426,7 @@ export const ModelsList: FC = () => { }, }) ); + await fetchModelsData(); } catch (e) { displayErrorToast( e, @@ -386,6 +437,7 @@ export const ModelsList: FC = () => { }, }) ); + setIsLoading(false); } }, }, @@ -400,9 +452,14 @@ export const ModelsList: FC = () => { type: 'icon', isPrimary: true, available: (item) => item.model_type === 'pytorch', - enabled: (item) => !isPopulatedObject(item.pipelines), + enabled: (item) => + !isLoading && + !isPopulatedObject(item.pipelines) && + isPopulatedObject(item.stats?.deployment_stats) && + item.stats?.deployment_stats?.state !== DEPLOYMENT_STATE.STOPPING, onClick: async (item) => { try { + setIsLoading(true); await trainedModelsApiService.stopModelAllocation(item.model_id); displaySuccessToast( i18n.translate('xpack.ml.trainedModels.modelsList.stopSuccess', { @@ -412,6 +469,8 @@ export const ModelsList: FC = () => { }, }) ); + // Need to fetch model state updates + await fetchModelsData(); } catch (e) { displayErrorToast( e, @@ -422,6 +481,7 @@ export const ModelsList: FC = () => { }, }) ); + setIsLoading(false); } }, }, @@ -521,13 +581,25 @@ export const ModelsList: FC = () => { ), 'data-test-subj': 'mlModelsTableColumnType', }, + { + name: i18n.translate('xpack.ml.trainedModels.modelsList.stateHeader', { + defaultMessage: 'State', + }), + sortable: (item) => item.stats?.deployment_stats?.state, + align: 'left', + render: (model: ModelItem) => { + const state = model.stats?.deployment_stats?.state; + return state ? {state} : null; + }, + 'data-test-subj': 'mlModelsTableColumnDeploymentState', + }, { field: ModelsTableToConfigMapping.createdAt, name: i18n.translate('xpack.ml.trainedModels.modelsList.createdAtHeader', { defaultMessage: 'Created at', }), dataType: 'date', - render: timeFormatter, + render: (v: number) => dateFormatter(v), sortable: true, 'data-test-subj': 'mlModelsTableColumnCreatedAt', }, diff --git a/x-pack/plugins/ml/public/application/trained_models/nodes_overview/allocated_models.tsx b/x-pack/plugins/ml/public/application/trained_models/nodes_overview/allocated_models.tsx new file mode 100644 index 0000000000000..2aad8183b7998 --- /dev/null +++ b/x-pack/plugins/ml/public/application/trained_models/nodes_overview/allocated_models.tsx @@ -0,0 +1,131 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { FC } from 'react'; +import { EuiBadge, EuiInMemoryTable, EuiToolTip } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { EuiBasicTableColumn } from '@elastic/eui/src/components/basic_table/basic_table'; +import type { + AllocatedModel, + NodeDeploymentStatsResponse, +} from '../../../../common/types/trained_models'; +import { useFieldFormatter } from '../../contexts/kibana/use_field_formatter'; +import { FIELD_FORMAT_IDS } from '../../../../../../../src/plugins/field_formats/common'; + +interface AllocatedModelsProps { + models: NodeDeploymentStatsResponse['allocated_models']; +} + +export const AllocatedModels: FC = ({ models }) => { + const bytesFormatter = useFieldFormatter(FIELD_FORMAT_IDS.BYTES); + const dateFormatter = useFieldFormatter(FIELD_FORMAT_IDS.DATE); + const durationFormatter = useFieldFormatter(FIELD_FORMAT_IDS.DURATION); + + const columns: Array> = [ + { + field: 'model_id', + name: i18n.translate('xpack.ml.trainedModels.nodesList.modelsList.modelNameHeader', { + defaultMessage: 'Name', + }), + width: '300px', + sortable: true, + truncateText: false, + 'data-test-subj': 'mlAllocatedModelsTableName', + }, + { + name: i18n.translate('xpack.ml.trainedModels.nodesList.modelsList.modelSizeHeader', { + defaultMessage: 'Size', + }), + width: '100px', + truncateText: true, + 'data-test-subj': 'mlAllocatedModelsTableSize', + render: (v: AllocatedModel) => { + return bytesFormatter(v.model_size_bytes); + }, + }, + { + field: 'state', + name: i18n.translate('xpack.ml.trainedModels.nodesList.modelsList.modelStateHeader', { + defaultMessage: 'State', + }), + width: '100px', + truncateText: false, + 'data-test-subj': 'mlAllocatedModelsTableState', + }, + { + name: i18n.translate( + 'xpack.ml.trainedModels.nodesList.modelsList.modelAvgInferenceTimeHeader', + { + defaultMessage: 'Avg inference time', + } + ), + width: '100px', + truncateText: false, + 'data-test-subj': 'mlAllocatedModelsTableAvgInferenceTime', + render: (v: AllocatedModel) => { + return v.node.average_inference_time_ms + ? durationFormatter(v.node.average_inference_time_ms) + : '-'; + }, + }, + { + name: i18n.translate( + 'xpack.ml.trainedModels.nodesList.modelsList.modelInferenceCountHeader', + { + defaultMessage: 'Inference count', + } + ), + width: '100px', + 'data-test-subj': 'mlAllocatedModelsTableInferenceCount', + render: (v: AllocatedModel) => { + return v.node.inference_count; + }, + }, + { + name: i18n.translate('xpack.ml.trainedModels.nodesList.modelsList.modelLastAccessHeader', { + defaultMessage: 'Last access', + }), + width: '200px', + 'data-test-subj': 'mlAllocatedModelsTableInferenceCount', + render: (v: AllocatedModel) => { + return dateFormatter(v.node.last_access); + }, + }, + { + name: i18n.translate('xpack.ml.trainedModels.nodesList.modelsList.modelRoutingStateHeader', { + defaultMessage: 'Routing state', + }), + width: '100px', + 'data-test-subj': 'mlAllocatedModelsTableRoutingState', + render: (v: AllocatedModel) => { + const { routing_state: routingState, reason } = v.node.routing_state; + + return ( + + {routingState} + + ); + }, + }, + ]; + + return ( + + allowNeutralSort={false} + columns={columns} + hasActions={false} + isExpandable={false} + isSelectable={false} + items={models} + itemId={'model_id'} + rowProps={(item) => ({ + 'data-test-subj': `mlAllocatedModelTableRow row-${item.model_id}`, + })} + onTableChange={() => {}} + data-test-subj={'mlNodesTable'} + /> + ); +}; diff --git a/x-pack/plugins/ml/public/application/trained_models/nodes_overview/expanded_row.tsx b/x-pack/plugins/ml/public/application/trained_models/nodes_overview/expanded_row.tsx index a32747185dcc8..508a5689e1c9b 100644 --- a/x-pack/plugins/ml/public/application/trained_models/nodes_overview/expanded_row.tsx +++ b/x-pack/plugins/ml/public/application/trained_models/nodes_overview/expanded_row.tsx @@ -9,17 +9,15 @@ import React, { FC } from 'react'; import { EuiDescriptionList, EuiFlexGrid, - EuiFlexGroup, EuiFlexItem, - EuiHorizontalRule, EuiPanel, EuiSpacer, - EuiTextColor, EuiTitle, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { NodeItemWithStats } from './nodes_list'; import { formatToListItems } from '../models_management/expanded_row'; +import { AllocatedModels } from './allocated_models'; interface ExpandedRowProps { item: NodeItemWithStats; @@ -55,8 +53,6 @@ export const ExpandedRow: FC = ({ item }) => { listItems={formatToListItems(details)} /> - -
@@ -76,10 +72,10 @@ export const ExpandedRow: FC = ({ item }) => { listItems={formatToListItems(attributes)} /> + - - - {allocatedModels.length > 0 ? ( + {allocatedModels.length > 0 ? ( +
@@ -91,34 +87,10 @@ export const ExpandedRow: FC = ({ item }) => { - {allocatedModels.map(({ model_id: modelId, ...rest }) => { - return ( - <> - - - - -
{modelId}
-
-
-
- - - -
- - - - - ); - })} + - ) : null} - + + ) : null} ); diff --git a/x-pack/plugins/ml/public/application/trained_models/nodes_overview/memory_preview_chart.tsx b/x-pack/plugins/ml/public/application/trained_models/nodes_overview/memory_preview_chart.tsx index ba790ba1c2576..dd9b6f8253860 100644 --- a/x-pack/plugins/ml/public/application/trained_models/nodes_overview/memory_preview_chart.tsx +++ b/x-pack/plugins/ml/public/application/trained_models/nodes_overview/memory_preview_chart.tsx @@ -8,25 +8,26 @@ import { i18n } from '@kbn/i18n'; import React, { FC, useMemo } from 'react'; import { - Chart, - Settings, - BarSeries, - ScaleType, Axis, + BarSeries, + Chart, Position, + ScaleType, SeriesColorAccessor, + Settings, } from '@elastic/charts'; import { euiPaletteGray } from '@elastic/eui'; import { NodeDeploymentStatsResponse } from '../../../../common/types/trained_models'; import { useFieldFormatter } from '../../contexts/kibana/use_field_formatter'; import { useCurrentEuiTheme } from '../../components/color_range_legend'; +import { FIELD_FORMAT_IDS } from '../../../../../../../src/plugins/field_formats/common'; interface MemoryPreviewChartProps { memoryOverview: NodeDeploymentStatsResponse['memory_overview']; } export const MemoryPreviewChart: FC = ({ memoryOverview }) => { - const bytesFormatter = useFieldFormatter('bytes'); + const bytesFormatter = useFieldFormatter(FIELD_FORMAT_IDS.BYTES); const { euiTheme } = useCurrentEuiTheme(); @@ -112,7 +113,7 @@ export const MemoryPreviewChart: FC = ({ memoryOverview tooltip={{ headerFormatter: ({ value }) => i18n.translate('xpack.ml.trainedModels.nodesList.memoryBreakdown', { - defaultMessage: 'Approximate memory breakdown based on the node info', + defaultMessage: 'Approximate memory breakdown', }), }} /> diff --git a/x-pack/plugins/ml/public/application/trained_models/nodes_overview/nodes_list.tsx b/x-pack/plugins/ml/public/application/trained_models/nodes_overview/nodes_list.tsx index 42e51f1ab2971..b1cc18e698c9d 100644 --- a/x-pack/plugins/ml/public/application/trained_models/nodes_overview/nodes_list.tsx +++ b/x-pack/plugins/ml/public/application/trained_models/nodes_overview/nodes_list.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { FC, useCallback, useMemo, useState } from 'react'; +import React, { FC, useCallback, useEffect, useMemo, useState } from 'react'; import { EuiButtonIcon, EuiFlexGroup, @@ -31,6 +31,8 @@ import { MemoryPreviewChart } from './memory_preview_chart'; import { useFieldFormatter } from '../../contexts/kibana/use_field_formatter'; import { ListingPageUrlState } from '../../../../common/types/common'; import { useToastNotificationService } from '../../services/toast_notification_service'; +import { FIELD_FORMAT_IDS } from '../../../../../../../src/plugins/field_formats/common'; +import { useRefresh } from '../../routing/use_refresh'; export type NodeItem = NodeDeploymentStatsResponse; @@ -47,8 +49,11 @@ export const getDefaultNodesListState = (): ListingPageUrlState => ({ export const NodesList: FC = () => { const trainedModelsApiService = useTrainedModelsApiService(); + + const refresh = useRefresh(); + const { displayErrorToast } = useToastNotificationService(); - const bytesFormatter = useFieldFormatter('bytes'); + const bytesFormatter = useFieldFormatter(FIELD_FORMAT_IDS.BYTES); const [items, setItems] = useState([]); const [isLoading, setIsLoading] = useState(false); const [itemIdToExpandedRowMap, setItemIdToExpandedRowMap] = useState>( @@ -179,6 +184,13 @@ export const NodesList: FC = () => { onRefresh: fetchNodesData, }); + useEffect( + function updateOnTimerRefresh() { + fetchNodesData(); + }, + [refresh] + ); + return ( <> diff --git a/x-pack/plugins/ml/public/application/trained_models/page.tsx b/x-pack/plugins/ml/public/application/trained_models/page.tsx index a6d99ca0fedc0..54849f3e651df 100644 --- a/x-pack/plugins/ml/public/application/trained_models/page.tsx +++ b/x-pack/plugins/ml/public/application/trained_models/page.tsx @@ -10,6 +10,7 @@ import React, { FC, Fragment, useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { + EuiBetaBadge, EuiFlexGroup, EuiFlexItem, EuiPage, @@ -21,6 +22,7 @@ import { } from '@elastic/eui'; import { useLocation } from 'react-router-dom'; +import { i18n } from '@kbn/i18n'; import { NavigationMenu } from '../components/navigation_menu'; import { ModelsList } from './models_management'; import { TrainedModelsNavigationBar } from './navigation_bar'; @@ -44,14 +46,35 @@ export const Page: FC = () => { - -

- + + +

+ +

+
+
+ + -

-
+ +
diff --git a/x-pack/plugins/ml/public/locator/formatters/trained_models.ts b/x-pack/plugins/ml/public/locator/formatters/trained_models.ts index d084c0675769f..9e1c5d92ce451 100644 --- a/x-pack/plugins/ml/public/locator/formatters/trained_models.ts +++ b/x-pack/plugins/ml/public/locator/formatters/trained_models.ts @@ -5,8 +5,13 @@ * 2.0. */ -import { TrainedModelsUrlState } from '../../../common/types/locator'; +import type { + TrainedModelsNodesUrlState, + TrainedModelsUrlState, +} from '../../../common/types/locator'; import { ML_PAGES } from '../../../common/constants/locator'; +import type { AppPageState, ListingPageUrlState } from '../../../common/types/common'; +import { setStateToKbnUrl } from '../../../../../../src/plugins/kibana_utils/public'; export function formatTrainedModelsManagementUrl( appBasePath: string, @@ -14,3 +19,31 @@ export function formatTrainedModelsManagementUrl( ): string { return `${appBasePath}/${ML_PAGES.TRAINED_MODELS_MANAGE}`; } + +export function formatTrainedModelsNodesManagementUrl( + appBasePath: string, + mlUrlGeneratorState: TrainedModelsNodesUrlState['pageState'] +): string { + let url = `${appBasePath}/${ML_PAGES.TRAINED_MODELS_NODES}`; + if (mlUrlGeneratorState) { + const { nodeId } = mlUrlGeneratorState; + if (nodeId) { + const nodesListState: Partial = { + queryText: `name:(${nodeId})`, + }; + + const queryState: AppPageState = { + [ML_PAGES.TRAINED_MODELS_NODES]: nodesListState, + }; + + url = setStateToKbnUrl>( + '_a', + queryState, + { useHash: false, storeInHashQuery: false }, + url + ); + } + } + + return url; +} diff --git a/x-pack/plugins/ml/public/locator/ml_locator.ts b/x-pack/plugins/ml/public/locator/ml_locator.ts index 7fa573c3e653d..c79c93078d04a 100644 --- a/x-pack/plugins/ml/public/locator/ml_locator.ts +++ b/x-pack/plugins/ml/public/locator/ml_locator.ts @@ -26,7 +26,10 @@ import { formatEditCalendarUrl, formatEditFilterUrl, } from './formatters'; -import { formatTrainedModelsManagementUrl } from './formatters/trained_models'; +import { + formatTrainedModelsManagementUrl, + formatTrainedModelsNodesManagementUrl, +} from './formatters/trained_models'; export type { MlLocatorParams, MlLocator }; @@ -70,6 +73,9 @@ export class MlLocatorDefinition implements LocatorDefinition { case ML_PAGES.TRAINED_MODELS_MANAGE: path = formatTrainedModelsManagementUrl('', params.pageState); break; + case ML_PAGES.TRAINED_MODELS_NODES: + path = formatTrainedModelsNodesManagementUrl('', params.pageState); + break; case ML_PAGES.ANOMALY_DETECTION_CREATE_JOB: case ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_ADVANCED: case ML_PAGES.DATA_VISUALIZER: diff --git a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts index 9e02a93a3c0f1..1cd9aae79777b 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts +++ b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts @@ -293,8 +293,6 @@ export class DataRecognizer { index, size, body: searchBody, - // Ignored indices that are frozen - ignore_throttled: true, }); // @ts-expect-error incorrect search response type diff --git a/x-pack/plugins/monitoring/server/deprecations.ts b/x-pack/plugins/monitoring/server/deprecations.ts index 42868e3fa2584..14c3b9cdc6474 100644 --- a/x-pack/plugins/monitoring/server/deprecations.ts +++ b/x-pack/plugins/monitoring/server/deprecations.ts @@ -23,27 +23,39 @@ export const deprecations = ({ }: ConfigDeprecationFactory): ConfigDeprecation[] => { return [ // This order matters. The "blanket rename" needs to happen at the end - renameFromRoot('xpack.monitoring.max_bucket_size', 'monitoring.ui.max_bucket_size'), - renameFromRoot('xpack.monitoring.min_interval_seconds', 'monitoring.ui.min_interval_seconds'), + renameFromRoot('xpack.monitoring.max_bucket_size', 'monitoring.ui.max_bucket_size', { + level: 'warning', + }), + renameFromRoot('xpack.monitoring.min_interval_seconds', 'monitoring.ui.min_interval_seconds', { + level: 'warning', + }), renameFromRoot( 'xpack.monitoring.show_license_expiration', - 'monitoring.ui.show_license_expiration' + 'monitoring.ui.show_license_expiration', + { level: 'warning' } ), renameFromRoot( 'xpack.monitoring.ui.container.elasticsearch.enabled', - 'monitoring.ui.container.elasticsearch.enabled' + 'monitoring.ui.container.elasticsearch.enabled', + { level: 'warning' } ), renameFromRoot( 'xpack.monitoring.ui.container.logstash.enabled', - 'monitoring.ui.container.logstash.enabled' + 'monitoring.ui.container.logstash.enabled', + { level: 'warning' } ), - renameFromRoot('xpack.monitoring.elasticsearch', 'monitoring.ui.elasticsearch'), - renameFromRoot('xpack.monitoring.ccs.enabled', 'monitoring.ui.ccs.enabled'), + renameFromRoot('xpack.monitoring.elasticsearch', 'monitoring.ui.elasticsearch', { + level: 'warning', + }), + renameFromRoot('xpack.monitoring.ccs.enabled', 'monitoring.ui.ccs.enabled', { + level: 'warning', + }), renameFromRoot( 'xpack.monitoring.elasticsearch.logFetchCount', - 'monitoring.ui.elasticsearch.logFetchCount' + 'monitoring.ui.elasticsearch.logFetchCount', + { level: 'warning' } ), - renameFromRoot('xpack.monitoring', 'monitoring'), + renameFromRoot('xpack.monitoring', 'monitoring', { level: 'warning' }), (config, fromPath, addDeprecation) => { const emailNotificationsEnabled = get(config, 'cluster_alerts.email_notifications.enabled'); if (emailNotificationsEnabled && !get(config, CLUSTER_ALERTS_ADDRESS_CONFIG_KEY)) { @@ -55,11 +67,14 @@ export const deprecations = ({ `Add [${fromPath}.${CLUSTER_ALERTS_ADDRESS_CONFIG_KEY}] to your kibana configs."`, ], }, + level: 'critical', }); } return config; }, - rename('xpack_api_polling_frequency_millis', 'licensing.api_polling_frequency'), + rename('xpack_api_polling_frequency_millis', 'licensing.api_polling_frequency', { + level: 'warning', + }), // TODO: Add deprecations for "monitoring.ui.elasticsearch.username: elastic" and "monitoring.ui.elasticsearch.username: kibana". // TODO: Add deprecations for using "monitoring.ui.elasticsearch.ssl.certificate" without "monitoring.ui.elasticsearch.ssl.key", and diff --git a/x-pack/plugins/observability/common/index.ts b/x-pack/plugins/observability/common/index.ts index bfb2eedf6deb2..6b4ea62c16762 100644 --- a/x-pack/plugins/observability/common/index.ts +++ b/x-pack/plugins/observability/common/index.ts @@ -6,7 +6,11 @@ */ export type { AsDuration, AsPercent } from './utils/formatters'; -export { enableInspectEsQueries, maxSuggestions } from './ui_settings_keys'; +export { + enableInspectEsQueries, + maxSuggestions, + enableComparisonByDefault, +} from './ui_settings_keys'; export const casesFeatureId = 'observabilityCases'; diff --git a/x-pack/plugins/observability/common/ui_settings_keys.ts b/x-pack/plugins/observability/common/ui_settings_keys.ts index 69eb507328719..4d34e216a017c 100644 --- a/x-pack/plugins/observability/common/ui_settings_keys.ts +++ b/x-pack/plugins/observability/common/ui_settings_keys.ts @@ -7,3 +7,4 @@ export const enableInspectEsQueries = 'observability:enableInspectEsQueries'; export const maxSuggestions = 'observability:maxSuggestions'; +export const enableComparisonByDefault = 'observability:enableComparisonByDefault'; diff --git a/x-pack/plugins/observability/public/index.ts b/x-pack/plugins/observability/public/index.ts index 3eebf8a84db19..a4ce62ddde0c7 100644 --- a/x-pack/plugins/observability/public/index.ts +++ b/x-pack/plugins/observability/public/index.ts @@ -85,3 +85,5 @@ export type { ExploratoryEmbeddableProps } from './components/shared/exploratory export type { AddInspectorRequest } from './context/inspector/inspector_context'; export { InspectorContextProvider } from './context/inspector/inspector_context'; export { useInspectorContext } from './context/inspector/use_inspector_context'; + +export { enableComparisonByDefault } from '../common/ui_settings_keys'; diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts_disclaimer.tsx b/x-pack/plugins/observability/public/pages/alerts/alerts_disclaimer.tsx index 6a57b08bf8d38..4bf71574ea7f9 100644 --- a/x-pack/plugins/observability/public/pages/alerts/alerts_disclaimer.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/alerts_disclaimer.tsx @@ -5,33 +5,68 @@ * 2.0. */ -import React from 'react'; -import { EuiLink, EuiCallOut } from '@elastic/eui'; +import React, { useState } from 'react'; +import { EuiLink, EuiCallOut, EuiButton, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; +const LOCAL_STORAGE_KEY_MSG_ACK = 'xpack.observability.alert.ack.experimental.message'; + export function AlertsDisclaimer() { + const getCurrentExperimentalMsgAckState = () => { + try { + const isExperimentalMsgAck = localStorage.getItem(LOCAL_STORAGE_KEY_MSG_ACK); + return isExperimentalMsgAck && JSON.parse(isExperimentalMsgAck) === true; + } catch { + return false; + } + }; + + const [experimentalMsgAck, setExperimentalMsgAck] = useState(getCurrentExperimentalMsgAckState); + + const dismissMessage = () => { + setExperimentalMsgAck(true); + localStorage.setItem(LOCAL_STORAGE_KEY_MSG_ACK, 'true'); + }; + return ( - - - {i18n.translate('xpack.observability.alertsDisclaimerLinkText', { - defaultMessage: 'feedback', - })} - - ), - }} - /> - + <> + {!experimentalMsgAck && ( + + + {i18n.translate('xpack.observability.alertsDisclaimerLinkText', { + defaultMessage: 'feedback', + })} + + ), + }} + /> + + + + {i18n.translate('xpack.observability.alertsDisclaimerDismissMessage', { + defaultMessage: 'Dismiss message', + })} + + + )} + ); } diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx b/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx index 9ffc12274675e..8c973dfb730f4 100644 --- a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx @@ -227,12 +227,14 @@ function ObservabilityActions({ event, casePermissions, appId: observabilityFeatureId, + owner: observabilityFeatureId, onClose: afterCaseSelection, }), timelines.getAddToNewCaseButton({ event, casePermissions, appId: observabilityFeatureId, + owner: observabilityFeatureId, onClose: afterCaseSelection, }), ] @@ -364,6 +366,7 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) { const sortDirection: SortDirection = 'desc'; return { appId: observabilityFeatureId, + casesOwner: observabilityFeatureId, casePermissions, type, columns, diff --git a/x-pack/plugins/observability/server/index.ts b/x-pack/plugins/observability/server/index.ts index d4d7127d8baee..d99cf0865c0dd 100644 --- a/x-pack/plugins/observability/server/index.ts +++ b/x-pack/plugins/observability/server/index.ts @@ -17,7 +17,7 @@ import { unwrapEsResponse, WrappedElasticsearchClientError, } from '../common/utils/unwrap_es_response'; -export { rangeQuery, kqlQuery } from './utils/queries'; +export { rangeQuery, kqlQuery, termQuery } from './utils/queries'; export { getInspectResponse } from '../common/utils/get_inspect_response'; export * from './types'; diff --git a/x-pack/plugins/observability/server/ui_settings.ts b/x-pack/plugins/observability/server/ui_settings.ts index 0bd9f99b5b145..ad0aa31542e8c 100644 --- a/x-pack/plugins/observability/server/ui_settings.ts +++ b/x-pack/plugins/observability/server/ui_settings.ts @@ -9,7 +9,11 @@ import { schema } from '@kbn/config-schema'; import { i18n } from '@kbn/i18n'; import { UiSettingsParams } from '../../../../src/core/types'; import { observabilityFeatureId } from '../common'; -import { enableInspectEsQueries, maxSuggestions } from '../common/ui_settings_keys'; +import { + enableComparisonByDefault, + enableInspectEsQueries, + maxSuggestions, +} from '../common/ui_settings_keys'; /** * uiSettings definitions for Observability. @@ -37,4 +41,15 @@ export const uiSettings: Record> = { }), schema: schema.number(), }, + [enableComparisonByDefault]: { + category: [observabilityFeatureId], + name: i18n.translate('xpack.observability.enableComparisonByDefault', { + defaultMessage: 'Comparison feature', + }), + value: true, + description: i18n.translate('xpack.observability.enableComparisonByDefaultDescription', { + defaultMessage: 'Enable the comparison feature on APM UI', + }), + schema: schema.boolean(), + }, }; diff --git a/x-pack/plugins/observability/server/utils/queries.ts b/x-pack/plugins/observability/server/utils/queries.ts index 953c0021636d4..54900cd46ea47 100644 --- a/x-pack/plugins/observability/server/utils/queries.ts +++ b/x-pack/plugins/observability/server/utils/queries.ts @@ -8,6 +8,14 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query'; +export function termQuery(field: T, value: string | undefined) { + if (!value) { + return []; + } + + return [{ term: { [field]: value } as Record }]; +} + export function rangeQuery( start?: number, end?: number, diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index 584f3ed334d89..5b846751d26df 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -5,8 +5,6 @@ * 2.0. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ENABLE_ITOM } from '../../actions/server/constants/connectors'; import type { TransformConfigSchema } from './transforms/types'; import { ENABLE_CASE_CONNECTOR } from '../../cases/common'; import { METADATA_TRANSFORMS_PATTERN } from './endpoint/constants'; @@ -326,6 +324,7 @@ export const NOTIFICATION_SUPPORTED_ACTION_TYPES_IDS = [ '.resilient', '.servicenow', '.servicenow-sir', + '.servicenow-itom', '.slack', '.swimlane', '.teams', @@ -336,11 +335,6 @@ if (ENABLE_CASE_CONNECTOR) { NOTIFICATION_SUPPORTED_ACTION_TYPES_IDS.push('.case'); } -// TODO: Remove when ITOM is ready -if (ENABLE_ITOM) { - NOTIFICATION_SUPPORTED_ACTION_TYPES_IDS.push('.servicenow-itom'); -} - export const NOTIFICATION_THROTTLE_NO_ACTIONS = 'no_actions' as const; export const NOTIFICATION_THROTTLE_RULE = 'rule' as const; diff --git a/x-pack/plugins/security_solution/cypress/integration/data_sources/create_runtime_field.spec.ts b/x-pack/plugins/security_solution/cypress/integration/data_sources/create_runtime_field.spec.ts new file mode 100644 index 0000000000000..1f2ca36c5a3d7 --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/integration/data_sources/create_runtime_field.spec.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { cleanKibana } from '../../tasks/common'; + +import { loginAndWaitForPage } from '../../tasks/login'; +import { openTimelineUsingToggle } from '../../tasks/security_main'; +import { openTimelineFieldsBrowser, populateTimeline } from '../../tasks/timeline'; + +import { HOSTS_URL, ALERTS_URL } from '../../urls/navigation'; + +import { waitForAlertsIndexToBeCreated, waitForAlertsPanelToBeLoaded } from '../../tasks/alerts'; +import { createCustomRuleActivated } from '../../tasks/api_calls/rules'; + +import { getNewRule } from '../../objects/rule'; +import { refreshPage } from '../../tasks/security_header'; +import { waitForAlertsToPopulate } from '../../tasks/create_new_rule'; +import { openEventsViewerFieldsBrowser } from '../../tasks/hosts/events'; + +describe('Create DataView runtime field', () => { + before(() => { + cleanKibana(); + }); + + it('adds field to alert table', () => { + const fieldName = 'field.name.alert.page'; + loginAndWaitForPage(ALERTS_URL); + waitForAlertsPanelToBeLoaded(); + waitForAlertsIndexToBeCreated(); + createCustomRuleActivated(getNewRule()); + refreshPage(); + waitForAlertsToPopulate(500); + openEventsViewerFieldsBrowser(); + + cy.get('[data-test-subj="create-field"]').click(); + cy.get('.indexPatternFieldEditorMaskOverlay').find('[data-test-subj="input"]').type(fieldName); + cy.get('[data-test-subj="fieldSaveButton"]').click(); + + cy.get( + `[data-test-subj="events-viewer-panel"] [data-test-subj="dataGridHeaderCell-${fieldName}"]` + ).should('exist'); + }); + + it('adds field to timeline', () => { + const fieldName = 'field.name.timeline'; + + loginAndWaitForPage(HOSTS_URL); + openTimelineUsingToggle(); + populateTimeline(); + openTimelineFieldsBrowser(); + + cy.get('[data-test-subj="create-field"]').click(); + cy.get('.indexPatternFieldEditorMaskOverlay').find('[data-test-subj="input"]').type(fieldName); + cy.get('[data-test-subj="fieldSaveButton"]').click(); + + cy.get(`[data-test-subj="timeline"] [data-test-subj="header-text-${fieldName}"]`).should( + 'exist' + ); + }); +}); diff --git a/x-pack/plugins/security_solution/kibana.json b/x-pack/plugins/security_solution/kibana.json index 80613ae12f51b..c2dfc7c923303 100644 --- a/x-pack/plugins/security_solution/kibana.json +++ b/x-pack/plugins/security_solution/kibana.json @@ -38,7 +38,8 @@ "lens", "lists", "home", - "telemetry" + "telemetry", + "indexPatternFieldEditor" ], "server": true, "ui": true, diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx index 5be966ab64980..8e62dfcb3c27b 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx @@ -9,7 +9,6 @@ import React, { useCallback, useMemo, useEffect } from 'react'; import { connect, ConnectedProps, useDispatch } from 'react-redux'; import deepEqual from 'fast-deep-equal'; import styled from 'styled-components'; - import { isEmpty } from 'lodash/fp'; import { inputsModel, inputsSelectors, State } from '../../store'; import { inputsActions } from '../../store/actions'; @@ -32,6 +31,7 @@ import { defaultControlColumn } from '../../../timelines/components/timeline/bod import { EventsViewer } from './events_viewer'; import * as i18n from './translations'; import { GraphOverlay } from '../../../timelines/components/graph_overlay'; +import { useCreateFieldButton } from '../../../timelines/components/create_field_button'; const EMPTY_CONTROL_COLUMNS: ControlColumnProps[] = []; const leadingControlColumns: ControlColumnProps[] = [ @@ -175,6 +175,8 @@ const StatefulEventsViewerComponent: React.FC = ({ }, [id, timelineQuery, globalQuery]); const bulkActions = useMemo(() => ({ onAlertStatusActionSuccess }), [onAlertStatusActionSuccess]); + const createFieldComponent = useCreateFieldButton(scopeId, id); + return ( <> @@ -218,6 +220,7 @@ const StatefulEventsViewerComponent: React.FC = ({ trailingControlColumns, type: 'embedded', unit, + createFieldComponent, }) ) : ( { useDispatch: () => mockDispatch, }; }); -jest.mock('../../lib/kibana'); // , () => ({ +jest.mock('../../lib/kibana'); describe('source/index.tsx', () => { describe('getBrowserFields', () => { @@ -40,11 +40,11 @@ describe('source/index.tsx', () => { expect(fields).toEqual({}); }); - test('it returns the same input with the same title', () => { - getBrowserFields('title 1', []); - // Since it is memoized it will return the same output which is empty object given 'title 1' a second time - const fields = getBrowserFields('title 1', mocksSource.indexFields as IndexField[]); - expect(fields).toEqual({}); + test('it returns the same input given the same title and same fields length', () => { + const oldFields = getBrowserFields('title 1', mocksSource.indexFields as IndexField[]); + const newFields = getBrowserFields('title 1', mocksSource.indexFields as IndexField[]); + // Since it is memoized it will return the same object instance + expect(newFields).toBe(oldFields); }); test('it transforms input into output as expected', () => { diff --git a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx index 1bbd484a33d1e..8ddd33d76034f 100644 --- a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx @@ -78,8 +78,7 @@ export const getBrowserFields = memoizeOne( return accumulator; }, {}); }, - // Update the value only if _title has changed - (newArgs, lastArgs) => newArgs[0] === lastArgs[0] + (newArgs, lastArgs) => newArgs[0] === lastArgs[0] && newArgs[1].length === lastArgs[1].length ); export const getDocValueFields = memoizeOne( @@ -97,8 +96,7 @@ export const getDocValueFields = memoizeOne( return accumulator; }, []) : [], - // Update the value only if _title has changed - (newArgs, lastArgs) => newArgs[0] === lastArgs[0] + (newArgs, lastArgs) => newArgs[0] === lastArgs[0] && newArgs[1].length === lastArgs[1].length ); export const indicesExistOrDataTemporarilyUnavailable = ( diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_secuirty_packages.test.tsx b/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_secuirty_packages.test.tsx index 968bd8679b23b..3e6dd399a3094 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_secuirty_packages.test.tsx +++ b/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_secuirty_packages.test.tsx @@ -9,6 +9,7 @@ import React, { memo } from 'react'; import { useKibana } from '../lib/kibana'; import { renderHook as _renderHook, RenderHookResult } from '@testing-library/react-hooks'; import { useUpgradeSecurityPackages } from './use_upgrade_security_packages'; +import { epmRouteService } from '../../../../fleet/common'; jest.mock('../components/user_privileges', () => { return { @@ -57,7 +58,7 @@ describe.skip('When using the `useUpgradeSecurityPackages()` hook', () => { ); expect(kibana.services.http.post).toHaveBeenCalledWith( - '/api/fleet/epm/packages/_bulk', + `${epmRouteService.getBulkInstallPath()}`, expect.objectContaining({ body: '{"packages":["endpoint","security_detection_engine"]}', }) diff --git a/x-pack/plugins/security_solution/public/common/utils/validators/index.test.ts b/x-pack/plugins/security_solution/public/common/utils/validators/index.test.ts index 2758a9724e897..2fbe0ed3e6bb8 100644 --- a/x-pack/plugins/security_solution/public/common/utils/validators/index.test.ts +++ b/x-pack/plugins/security_solution/public/common/utils/validators/index.test.ts @@ -14,19 +14,19 @@ describe('helpers', () => { }); test('should verify as invalid url without http(s):// prefix', () => { - expect(isUrlInvalid('www.thisIsNotValid.com')).toBeTruthy(); + expect(isUrlInvalid('www.thisIsNotValid.com/foo')).toBeTruthy(); }); test('verifies valid url', () => { - expect(isUrlInvalid('https://www.elastic.co/')).toBeFalsy(); + expect(isUrlInvalid('https://www.elastic.co/foo')).toBeFalsy(); }); test('should verify valid wwww such as 4 of them.', () => { - expect(isUrlInvalid('https://wwww.example.com')).toBeFalsy(); + expect(isUrlInvalid('https://wwww.example.com/foo')).toBeFalsy(); }); test('should validate characters such as %22 being part of a correct URL.', () => { - expect(isUrlInvalid('https://www.exam%22ple.com')).toBeFalsy(); + expect(isUrlInvalid('https://www.exam%22ple.com/foo')).toBeFalsy(); }); test('should validate characters incorrectly such as ]', () => { @@ -34,7 +34,7 @@ describe('helpers', () => { }); test('should verify valid http url', () => { - expect(isUrlInvalid('http://www.example.com/')).toBeFalsy(); + expect(isUrlInvalid('http://www.example.com/foo')).toBeFalsy(); }); test('should verify as valid when given an empty string', () => { @@ -44,5 +44,9 @@ describe('helpers', () => { test('empty spaces should valid as not valid ', () => { expect(isUrlInvalid(' ')).toBeTruthy(); }); + + test('should verify as invalid url without //', () => { + expect(isUrlInvalid('http:www.thisIsNotValid.com/foo')).toBeTruthy(); + }); }); }); diff --git a/x-pack/plugins/security_solution/public/common/utils/validators/index.ts b/x-pack/plugins/security_solution/public/common/utils/validators/index.ts index 7f0e8c30177f8..6989e27fc779d 100644 --- a/x-pack/plugins/security_solution/public/common/utils/validators/index.ts +++ b/x-pack/plugins/security_solution/public/common/utils/validators/index.ts @@ -16,7 +16,10 @@ export const isUrlInvalid = (url: string | null | undefined) => { return false; } else { const urlParsed = new URL(url); - if (allowedSchemes.includes(urlParsed.protocol)) { + if ( + allowedSchemes.includes(urlParsed.protocol) && + url.startsWith(`${urlParsed.protocol}//`) + ) { return false; } } diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_to_case_actions.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_to_case_actions.tsx index a342b01b038ca..708c3c396d0d1 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_to_case_actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_to_case_actions.tsx @@ -8,7 +8,7 @@ import { useMemo } from 'react'; import { useGetUserCasesPermissions, useKibana } from '../../../../common/lib/kibana'; import { TimelineId, TimelineNonEcsData } from '../../../../../common'; -import { APP_ID } from '../../../../../common/constants'; +import { APP_ID, APP_UI_ID } from '../../../../../common/constants'; import { useInsertTimeline } from '../../../../cases/components/use_insert_timeline'; import { Ecs } from '../../../../../common/ecs'; @@ -39,7 +39,8 @@ export const useAddToCaseActions = ({ event: { data: nonEcsData ?? [], ecs: ecsData, _id: ecsData?._id }, useInsertTimeline: insertTimelineHook, casePermissions, - appId: APP_ID, + appId: APP_UI_ID, + owner: APP_ID, onClose: afterCaseSelection, } : null, diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/translations.ts b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/translations.ts index 48516aa203b68..f1841430f03ff 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/translations.ts @@ -73,7 +73,7 @@ export const CRITICAL = i18n.translate( export const URL_FORMAT_INVALID = i18n.translate( 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.referencesUrlInvalidError', { - defaultMessage: 'Url is invalid format', + defaultMessage: 'URL is invalid format', } ); diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx index 45dcf5f7a0f7d..c6d41fbdc4b1b 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx @@ -50,7 +50,10 @@ import { TRANSFORM_STATES, } from '../../../../../common/constants'; import { TransformStats } from '../types'; -import { metadataTransformPrefix } from '../../../../../common/endpoint/constants'; +import { + metadataTransformPrefix, + METADATA_UNITED_TRANSFORM, +} from '../../../../../common/endpoint/constants'; // not sure why this can't be imported from '../../../../common/mock/formatted_relative'; // but sure enough it needs to be inline in this one file @@ -1457,5 +1460,23 @@ describe('when on the endpoint list page', () => { const banner = await screen.findByTestId('callout-endpoints-list-transform-failed'); expect(banner).toBeInTheDocument(); }); + + it('displays correct transform id when in failed state', async () => { + const transforms: TransformStats[] = [ + { + id: `${metadataTransformPrefix}-0.20.0`, + state: TRANSFORM_STATES.STARTED, + } as TransformStats, + { + id: `${METADATA_UNITED_TRANSFORM}-1.2.1`, + state: TRANSFORM_STATES.FAILED, + } as TransformStats, + ]; + setEndpointListApiMockImplementation(coreStart.http, { transforms }); + render(); + const banner = await screen.findByTestId('callout-endpoints-list-transform-failed'); + expect(banner).not.toHaveTextContent(transforms[0].id); + expect(banner).toHaveTextContent(transforms[1].id); + }); }); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx index 7845409353898..7332510736534 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx @@ -534,14 +534,19 @@ export const EndpointList = () => { return endpointsExist && !patternsError; }, [endpointsExist, patternsError]); - const transformFailedCalloutDescription = useMemo( - () => ( + const transformFailedCalloutDescription = useMemo(() => { + const failingTransformIds = metadataTransformStats + .filter((transformStat) => WARNING_TRANSFORM_STATES.has(transformStat.state)) + .map((transformStat) => transformStat.id) + .join(', '); + + return ( <> { docsPage: ( { /> - ), - [metadataTransformStats, services?.docLinks?.links.transforms.guide] - ); + ); + }, [metadataTransformStats, services?.docLinks?.links.endpoints.troubleshooting]); const transformFailedCallout = useMemo(() => { if (!showTransformFailedCallout) { diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/store/services/ingest.test.ts b/x-pack/plugins/security_solution/public/management/pages/policy/store/services/ingest.test.ts index 9de5e2806e857..b5897d8fd3bc4 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/store/services/ingest.test.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/store/services/ingest.test.ts @@ -12,7 +12,12 @@ import { sendGetEndpointSpecificPackagePolicies, } from './ingest'; import { httpServiceMock } from '../../../../../../../../../src/core/public/mocks'; -import { PACKAGE_POLICY_SAVED_OBJECT_TYPE } from '../../../../../../../fleet/common'; +import { + EPM_API_ROUTES, + PACKAGE_POLICY_SAVED_OBJECT_TYPE, + PACKAGE_POLICY_API_ROOT, + PACKAGE_POLICY_API_ROUTES, +} from '../../../../../../../fleet/common'; import { policyListApiPathHandlers } from '../test_mock_utils'; describe('ingest service', () => { @@ -25,7 +30,7 @@ describe('ingest service', () => { describe('sendGetEndpointSpecificPackagePolicies()', () => { it('auto adds kuery to api request', async () => { await sendGetEndpointSpecificPackagePolicies(http); - expect(http.get).toHaveBeenCalledWith('/api/fleet/package_policies', { + expect(http.get).toHaveBeenCalledWith(`${PACKAGE_POLICY_API_ROUTES.LIST_PATTERN}`, { query: { kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name: endpoint`, }, @@ -35,7 +40,7 @@ describe('ingest service', () => { await sendGetEndpointSpecificPackagePolicies(http, { query: { kuery: 'someValueHere', page: 1, perPage: 10 }, }); - expect(http.get).toHaveBeenCalledWith('/api/fleet/package_policies', { + expect(http.get).toHaveBeenCalledWith(`${PACKAGE_POLICY_API_ROUTES.LIST_PATTERN}`, { query: { kuery: `someValueHere and ${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name: endpoint`, perPage: 10, @@ -48,11 +53,11 @@ describe('ingest service', () => { describe('sendGetPackagePolicy()', () => { it('builds correct API path', async () => { await sendGetPackagePolicy(http, '123'); - expect(http.get).toHaveBeenCalledWith('/api/fleet/package_policies/123', undefined); + expect(http.get).toHaveBeenCalledWith(`${PACKAGE_POLICY_API_ROOT}/123`, undefined); }); it('supports http options', async () => { await sendGetPackagePolicy(http, '123', { query: { page: 1 } }); - expect(http.get).toHaveBeenCalledWith('/api/fleet/package_policies/123', { + expect(http.get).toHaveBeenCalledWith(`${PACKAGE_POLICY_API_ROOT}/123`, { query: { page: 1, }, @@ -66,7 +71,7 @@ describe('ingest service', () => { Promise.resolve(policyListApiPathHandlers()[INGEST_API_EPM_PACKAGES]()) ); await sendGetEndpointSecurityPackage(http); - expect(http.get).toHaveBeenCalledWith('/api/fleet/epm/packages', { + expect(http.get).toHaveBeenCalledWith(`${EPM_API_ROUTES.LIST_PATTERN}`, { query: { category: 'security' }, }); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx index c176ce9cacd43..2e763f3f4eaf3 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx @@ -13,6 +13,7 @@ import { EndpointDocGenerator } from '../../../../../common/endpoint/generate_da import { AppContextTestRender, createAppRootMockRenderer } from '../../../../common/mock/endpoint'; import { getPolicyDetailPath, getEndpointListPath } from '../../../common/routing'; import { policyListApiPathHandlers } from '../store/test_mock_utils'; +import { PACKAGE_POLICY_API_ROOT, AGENT_API_ROUTES } from '../../../../../../fleet/common'; jest.mock('./policy_forms/components/policy_form_layout'); @@ -80,7 +81,7 @@ describe('Policy Details', () => { const [path] = args; if (typeof path === 'string') { // GET datasouce - if (path === '/api/fleet/package_policies/1') { + if (path === `${PACKAGE_POLICY_API_ROOT}/1`) { asyncActions = asyncActions.then(async (): Promise => sleep()); return Promise.resolve({ item: policyPackagePolicy, @@ -89,7 +90,7 @@ describe('Policy Details', () => { } // GET Agent status for agent policy - if (path === '/api/fleet/agent-status') { + if (path === `${AGENT_API_ROUTES.STATUS_PATTERN}`) { asyncActions = asyncActions.then(async () => sleep()); return Promise.resolve({ results: { events: 0, total: 5, online: 3, error: 1, offline: 1 }, diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.test.tsx index 28f2ecf7eb98e..2702aec1cbabe 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.test.tsx @@ -18,6 +18,7 @@ import { import { getPolicyDetailPath, getEndpointListPath } from '../../../../../common/routing'; import { policyListApiPathHandlers } from '../../../store/test_mock_utils'; import { licenseService } from '../../../../../../common/hooks/use_license'; +import { PACKAGE_POLICY_API_ROOT, AGENT_API_ROUTES } from '../../../../../../../../fleet/common'; jest.mock('../../../../../../common/hooks/use_license'); @@ -64,7 +65,7 @@ describe('Policy Form Layout', () => { const [path] = args; if (typeof path === 'string') { // GET datasouce - if (path === '/api/fleet/package_policies/1') { + if (path === `${PACKAGE_POLICY_API_ROOT}/1`) { asyncActions = asyncActions.then(async (): Promise => sleep()); return Promise.resolve({ item: policyPackagePolicy, @@ -73,7 +74,7 @@ describe('Policy Form Layout', () => { } // GET Agent status for agent policy - if (path === '/api/fleet/agent-status') { + if (path === `${AGENT_API_ROUTES.STATUS_PATTERN}`) { asyncActions = asyncActions.then(async () => sleep()); return Promise.resolve({ results: { events: 0, total: 5, online: 3, error: 1, offline: 1 }, @@ -156,7 +157,7 @@ describe('Policy Form Layout', () => { asyncActions = asyncActions.then(async () => sleep()); const [path] = args; if (typeof path === 'string') { - if (path === '/api/fleet/package_policies/1') { + if (path === `${PACKAGE_POLICY_API_ROOT}/1`) { return Promise.resolve({ item: policyPackagePolicy, success: true, @@ -201,7 +202,7 @@ describe('Policy Form Layout', () => { // API should be called await asyncActions; - expect(http.put.mock.calls[0][0]).toEqual(`/api/fleet/package_policies/1`); + expect(http.put.mock.calls[0][0]).toEqual(`${PACKAGE_POLICY_API_ROOT}/1`); policyFormLayoutView.update(); // Toast notification should be shown diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/layout/policy_trusted_apps_layout.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/layout/policy_trusted_apps_layout.test.tsx index dbb18a1b0f2ef..318b98712a7c0 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/layout/policy_trusted_apps_layout.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/layout/policy_trusted_apps_layout.test.tsx @@ -21,6 +21,7 @@ import { EndpointDocGenerator } from '../../../../../../../common/endpoint/gener import { policyListApiPathHandlers } from '../../../store/test_mock_utils'; import { useEndpointPrivileges } from '../../../../../../common/components/user_privileges/endpoint/use_endpoint_privileges'; import { getEndpointPrivilegesInitialStateMock } from '../../../../../../common/components/user_privileges/endpoint/mocks'; +import { PACKAGE_POLICY_API_ROOT, AGENT_API_ROUTES } from '../../../../../../../../fleet/common'; jest.mock('../../../../trusted_apps/service'); jest.mock('../../../../../../common/components/user_privileges/endpoint/use_endpoint_privileges'); @@ -43,7 +44,7 @@ describe('Policy trusted apps layout', () => { const [path] = args; if (typeof path === 'string') { // GET datasouce - if (path === '/api/fleet/package_policies/1234') { + if (path === `${PACKAGE_POLICY_API_ROOT}/1234`) { return Promise.resolve({ item: generator.generatePolicyPackagePolicy(), success: true, @@ -51,7 +52,7 @@ describe('Policy trusted apps layout', () => { } // GET Agent status for agent policy - if (path === '/api/fleet/agent-status') { + if (path === `${AGENT_API_ROUTES.STATUS_PATTERN}`) { return Promise.resolve({ results: { events: 0, total: 5, online: 3, error: 1, offline: 1 }, success: true, diff --git a/x-pack/plugins/security_solution/public/timelines/components/create_field_button/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/create_field_button/index.test.tsx new file mode 100644 index 0000000000000..4fb2b9419c377 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/create_field_button/index.test.tsx @@ -0,0 +1,90 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { render, fireEvent, act, screen } from '@testing-library/react'; +import React from 'react'; +import { CreateFieldButton } from './index'; +import { + indexPatternFieldEditorPluginMock, + Start, +} from '../../../../../../../src/plugins/index_pattern_field_editor/public/mocks'; + +import { TestProviders } from '../../../common/mock'; +import { useKibana } from '../../../common/lib/kibana'; +import { DataView } from '../../../../../../../src/plugins/data/common'; +import { TimelineId } from '../../../../common'; + +const useKibanaMock = useKibana as jest.Mocked; + +let mockIndexPatternFieldEditor: Start; +jest.mock('../../../common/lib/kibana'); + +const runAllPromises = () => new Promise(setImmediate); + +describe('CreateFieldButton', () => { + beforeEach(() => { + mockIndexPatternFieldEditor = indexPatternFieldEditorPluginMock.createStartContract(); + useKibanaMock().services.indexPatternFieldEditor = mockIndexPatternFieldEditor; + useKibanaMock().services.data.dataViews.get = () => new Promise(() => undefined); + }); + + it('displays the button when user has permissions', () => { + mockIndexPatternFieldEditor.userPermissions.editIndexPattern = () => true; + + render( + undefined} + timelineId={TimelineId.detectionsPage} + />, + { + wrapper: TestProviders, + } + ); + + expect(screen.getByRole('button')).toBeInTheDocument(); + }); + + it("doesn't display the button when user doesn't have permissions", () => { + mockIndexPatternFieldEditor.userPermissions.editIndexPattern = () => false; + render( + undefined} + timelineId={TimelineId.detectionsPage} + />, + { + wrapper: TestProviders, + } + ); + + expect(screen.queryByRole('button')).not.toBeInTheDocument(); + }); + + it("calls 'onClick' param when the button is clicked", async () => { + mockIndexPatternFieldEditor.userPermissions.editIndexPattern = () => true; + useKibanaMock().services.data.dataViews.get = () => Promise.resolve({} as DataView); + + const onClickParam = jest.fn(); + await act(async () => { + render( + , + { + wrapper: TestProviders, + } + ); + await runAllPromises(); + }); + + fireEvent.click(screen.getByRole('button')); + expect(onClickParam).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/timelines/components/create_field_button/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/create_field_button/index.tsx new file mode 100644 index 0000000000000..33d8587eca818 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/create_field_button/index.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { EuiButton } from '@elastic/eui'; +import styled from 'styled-components'; + +import { useDispatch } from 'react-redux'; +import { IndexPattern, IndexPatternField } from '../../../../../../../src/plugins/data/public'; +import { useKibana } from '../../../common/lib/kibana'; + +import * as i18n from './translations'; +import { CreateFieldComponentType, TimelineId } from '../../../../../timelines/common'; +import { tGridActions } from '../../../../../timelines/public'; +import { useDataView } from '../../../common/containers/source/use_data_view'; +import { SourcererScopeName } from '../../../common/store/sourcerer/model'; +import { sourcererSelectors } from '../../../common/store'; +import { useDeepEqualSelector } from '../../../common/hooks/use_selector'; +import { DEFAULT_COLUMN_MIN_WIDTH } from '../timeline/body/constants'; +import { defaultColumnHeaderType } from '../timeline/body/column_headers/default_headers'; + +interface CreateFieldButtonProps { + selectedDataViewId: string; + onClick: () => void; + timelineId: TimelineId; +} +const StyledButton = styled(EuiButton)` + margin-left: ${({ theme }) => theme.eui.paddingSizes.m}; +`; + +export const CreateFieldButton = React.memo( + ({ selectedDataViewId, onClick: onClickParam, timelineId }) => { + const [dataView, setDataView] = useState(null); + const dispatch = useDispatch(); + + const { indexFieldsSearch } = useDataView(); + const { + indexPatternFieldEditor, + data: { dataViews }, + } = useKibana().services; + + useEffect(() => { + dataViews.get(selectedDataViewId).then((dataViewResponse) => { + setDataView(dataViewResponse); + }); + }, [selectedDataViewId, dataViews]); + + const onClick = useCallback(() => { + if (dataView) { + indexPatternFieldEditor?.openEditor({ + ctx: { indexPattern: dataView }, + onSave: (field: IndexPatternField) => { + // Fetch the updated list of fields + indexFieldsSearch(selectedDataViewId); + + // Add the new field to the event table + dispatch( + tGridActions.upsertColumn({ + column: { + columnHeaderType: defaultColumnHeaderType, + id: field.name, + initialWidth: DEFAULT_COLUMN_MIN_WIDTH, + }, + id: timelineId, + index: 0, + }) + ); + }, + }); + } + onClickParam(); + }, [ + indexPatternFieldEditor, + dataView, + onClickParam, + indexFieldsSearch, + selectedDataViewId, + dispatch, + timelineId, + ]); + + if (!indexPatternFieldEditor?.userPermissions.editIndexPattern()) { + return null; + } + + return ( + <> + + {i18n.CREATE_FIELD} + + + ); + } +); + +CreateFieldButton.displayName = 'CreateFieldButton'; + +/** + * + * Returns a memoised 'CreateFieldButton' with only an 'onClick' property. + */ +export const useCreateFieldButton = ( + sourcererScope: SourcererScopeName, + timelineId: TimelineId +) => { + const scopeIdSelector = useMemo(() => sourcererSelectors.scopeIdSelector(), []); + const { selectedDataViewId } = useDeepEqualSelector((state) => + scopeIdSelector(state, sourcererScope) + ); + + const createFieldComponent = useMemo(() => { + // It receives onClick props from field browser in order to close the modal. + const CreateFieldButtonComponent: CreateFieldComponentType = ({ onClick }) => ( + + ); + + return CreateFieldButtonComponent; + }, [selectedDataViewId, timelineId]); + + return createFieldComponent; +}; diff --git a/x-pack/plugins/security_solution/public/timelines/components/create_field_button/translations.ts b/x-pack/plugins/security_solution/public/timelines/components/create_field_button/translations.ts new file mode 100644 index 0000000000000..cc655b10849a5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/create_field_button/translations.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const CREATE_FIELD = i18n.translate( + 'xpack.securitySolution.fieldBrowser.createFieldButton', + { + defaultMessage: 'Create field', + } +); diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx index 2afb2af01406d..dd50f00b23eae 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx @@ -7,7 +7,7 @@ import { EuiFlyout, EuiFlyoutProps } from '@elastic/eui'; import React, { useCallback } from 'react'; -import styled from 'styled-components'; +import styled, { createGlobalStyle } from 'styled-components'; import { useDispatch } from 'react-redux'; import { StatefulTimeline } from '../../timeline'; @@ -29,6 +29,17 @@ const StyledEuiFlyout = styled(EuiFlyout)` z-index: ${({ theme }) => theme.eui.euiZLevel4}; `; +// SIDE EFFECT: the following creates a global class selector +const IndexPatternFieldEditorOverlayGlobalStyle = createGlobalStyle<{ + theme: { eui: { euiZLevel5: number } }; +}>` + .indexPatternFieldEditorMaskOverlay { + ${({ theme }) => ` + z-index: ${theme.eui.euiZLevel5}; + `} + } +`; + const FlyoutPaneComponent: React.FC = ({ timelineId, visible = true, @@ -51,6 +62,7 @@ const FlyoutPaneComponent: React.FC = ({ ownFocus={false} style={{ visibility: visible ? 'visible' : 'hidden' }} > + = ({ sort, tabType, timelineId, + createFieldComponent, }) => { const { timelines: timelinesUi } = useKibana().services; const { globalFullScreen, setGlobalFullScreen } = useGlobalFullScreen(); @@ -183,6 +184,7 @@ const HeaderActionsComponent: React.FC = ({ browserFields, columnHeaders, timelineId, + createFieldComponent, })} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx index 25aefd513f806..80a9022105d2c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx @@ -33,6 +33,9 @@ import { import { Sort } from '../sort'; import { ColumnHeader } from './column_header'; +import { SourcererScopeName } from '../../../../../common/store/sourcerer/model'; +import { useCreateFieldButton } from '../../../create_field_button'; + interface Props { actionsColumnWidth: number; browserFields: BrowserFields; @@ -169,6 +172,11 @@ export const ColumnHeadersComponent = ({ [trailingControlColumns] ); + const createFieldComponent = useCreateFieldButton( + SourcererScopeName.timeline, + timelineId as TimelineId + ); + const LeadingHeaderActions = useMemo(() => { return leadingHeaderCells.map( (Header: React.ComponentType | React.ComponentType | undefined, index) => { @@ -194,6 +202,7 @@ export const ColumnHeadersComponent = ({ sort={sort} tabType={tabType} timelineId={timelineId} + createFieldComponent={createFieldComponent} /> )} @@ -206,6 +215,7 @@ export const ColumnHeadersComponent = ({ actionsColumnWidth, browserFields, columnHeaders, + createFieldComponent, isEventViewer, isSelectAllChecked, onSelectAll, @@ -241,6 +251,7 @@ export const ColumnHeadersComponent = ({ sort={sort} tabType={tabType} timelineId={timelineId} + createFieldComponent={createFieldComponent} /> )} @@ -253,6 +264,7 @@ export const ColumnHeadersComponent = ({ actionsColumnWidth, browserFields, columnHeaders, + createFieldComponent, isEventViewer, isSelectAllChecked, onSelectAll, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx index 9509ae0eb7838..586109f7f68a7 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx @@ -27,7 +27,6 @@ import { defaultRowRenderers } from './renderers'; jest.mock('../../../../common/lib/kibana/hooks'); jest.mock('../../../../common/hooks/use_app_toasts'); - jest.mock('../../../../common/lib/kibana', () => { const originalModule = jest.requireActual('../../../../common/lib/kibana'); return { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.test.tsx index ef8fa01a63465..30b4582096322 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.test.tsx @@ -161,3 +161,116 @@ describe('DefaultCellRenderer', () => { ).toBeTruthy(); }); }); + +describe('host link rendering', () => { + const data = cloneDeep(mockTimelineData[0].data); + const hostNameHeader = cloneDeep(defaultHeaders[4]); + + beforeEach(() => { + const { getColumnRenderer: realGetColumnRenderer } = jest.requireActual( + '../body/renderers/get_column_renderer' + ); + + getColumnRendererMock.mockImplementation(realGetColumnRenderer); // link rendering tests must use the real renderer + }); + + test('it renders a link button for `host.name` when `isTimeline` is true', () => { + const id = 'host.name'; + const isTimeline = true; + + const wrapper = mount( + + + + + + + + ); + + expect(wrapper.find('[data-test-subj="host-details-button"]').first().text()).toEqual('apache'); + }); + + test('it does NOT render a link button for `host.name` when `isTimeline` is false', () => { + const id = 'host.name'; + const isTimeline = false; + + const wrapper = mount( + + + + + + + + ); + + expect(wrapper.find('[data-test-subj="host-details-button"]').exists()).toBe(false); + }); + + test('it does NOT render a link button for non-host fields when `isTimeline` is true', () => { + const id = '@timestamp'; // a non-host field + const isTimeline = true; + const timestampHeader = cloneDeep(defaultHeaders[0]); + + const wrapper = mount( + + + + + + + + ); + + expect(wrapper.find('[data-test-subj="host-details-button"]').exists()).toBe(false); + }); +}); diff --git a/x-pack/plugins/security_solution/public/types.ts b/x-pack/plugins/security_solution/public/types.ts index 376cfbf31afe2..7c0b8d46b8bba 100644 --- a/x-pack/plugins/security_solution/public/types.ts +++ b/x-pack/plugins/security_solution/public/types.ts @@ -41,6 +41,7 @@ import { Management } from './management'; import { Ueba } from './ueba'; import { LicensingPluginStart, LicensingPluginSetup } from '../../licensing/public'; import { DashboardStart } from '../../../../src/plugins/dashboard/public'; +import { IndexPatternFieldEditorStart } from '../../../../src/plugins/index_pattern_field_editor/public'; export interface SetupPlugins { home?: HomePublicPluginSetup; @@ -67,6 +68,7 @@ export interface StartPlugins { uiActions: UiActionsStart; ml?: MlPluginStart; spaces?: SpacesPluginStart; + indexPatternFieldEditor: IndexPatternFieldEditorStart; } export type StartServices = CoreStart & diff --git a/x-pack/plugins/timelines/common/types/timeline/actions/index.ts b/x-pack/plugins/timelines/common/types/timeline/actions/index.ts index e85f2eaa12d72..dd4a84be2eb69 100644 --- a/x-pack/plugins/timelines/common/types/timeline/actions/index.ts +++ b/x-pack/plugins/timelines/common/types/timeline/actions/index.ts @@ -7,7 +7,7 @@ import { ComponentType, JSXElementConstructor } from 'react'; import { EuiDataGridControlColumn, EuiDataGridCellValueElementProps } from '@elastic/eui'; -import { OnRowSelected, SortColumnTimeline, TimelineTabs } from '..'; +import { CreateFieldComponentType, OnRowSelected, SortColumnTimeline, TimelineTabs } from '..'; import { BrowserFields } from '../../../search_strategy/index_fields'; import { ColumnHeaderOptions } from '../columns'; import { TimelineNonEcsData } from '../../../search_strategy'; @@ -67,6 +67,7 @@ export interface HeaderActionProps { width: number; browserFields: BrowserFields; columnHeaders: ColumnHeaderOptions[]; + createFieldComponent?: CreateFieldComponentType; isEventViewer?: boolean; isSelectAllChecked: boolean; onSelectAll: ({ isSelected }: { isSelected: boolean }) => void; diff --git a/x-pack/plugins/timelines/common/types/timeline/index.ts b/x-pack/plugins/timelines/common/types/timeline/index.ts index c57f247493ffc..e4ce670e87c9f 100644 --- a/x-pack/plugins/timelines/common/types/timeline/index.ts +++ b/x-pack/plugins/timelines/common/types/timeline/index.ts @@ -467,6 +467,10 @@ export enum TimelineTabs { eql = 'eql', } +export type CreateFieldComponentType = React.FC<{ + onClick: () => void; +}>; + // eslint-disable-next-line @typescript-eslint/no-explicit-any type EmptyObject = Partial>; diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action.test.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action.test.tsx index 19206c40d18c2..fb0a5ebcbbf9e 100644 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action.test.tsx +++ b/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action.test.tsx @@ -35,7 +35,8 @@ describe('AddToCaseAction', () => { crud: true, read: true, }, - appId: 'securitySolution', + appId: 'securitySolutionUI', + owner: 'securitySolution', onClose: () => null, }; diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action.tsx index 73be0c13faf51..c8517a26f6295 100644 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action.tsx +++ b/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action.tsx @@ -25,6 +25,7 @@ export interface AddToCaseActionProps { read: boolean; } | null; appId: string; + owner: string; onClose?: Function; disableAlerts?: boolean; } @@ -35,6 +36,7 @@ const AddToCaseActionComponent: React.FC = ({ useInsertTimeline, casePermissions, appId, + owner, onClose, disableAlerts, }) => { @@ -50,7 +52,7 @@ const AddToCaseActionComponent: React.FC = ({ createCaseUrl, isAllCaseModalOpen, isCreateCaseFlyoutOpen, - } = useAddToCase({ event, useInsertTimeline, casePermissions, appId, onClose }); + } = useAddToCase({ event, useInsertTimeline, casePermissions, appId, owner, onClose }); const getAllCasesSelectorModalProps = useMemo(() => { const { ruleId, ruleName } = normalizedEventFields(event); @@ -62,7 +64,7 @@ const AddToCaseActionComponent: React.FC = ({ id: ruleId, name: ruleName, }, - owner: appId, + owner, }, createCaseNavigation: { href: createCaseUrl, @@ -75,7 +77,7 @@ const AddToCaseActionComponent: React.FC = ({ onRowClick: onCaseClicked, updateCase: onCaseSuccess, userCanCrud: casePermissions?.crud ?? false, - owner: [appId], + owner: [owner], onClose: () => dispatch(tGridActions.setOpenAddToExistingCase({ id: eventId, isOpen: false })), }; @@ -87,8 +89,8 @@ const AddToCaseActionComponent: React.FC = ({ goToCreateCase, eventId, eventIndex, - appId, dispatch, + owner, useInsertTimeline, event, ]); @@ -105,7 +107,7 @@ const AddToCaseActionComponent: React.FC = ({ onCloseFlyout={closeCaseFlyoutOpen} onSuccess={onCaseSuccess} useInsertTimeline={useInsertTimeline} - appId={appId} + owner={owner} disableAlerts={disableAlerts} /> )} diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action_button.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action_button.tsx index 28821028af3c7..460f22d55061a 100644 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action_button.tsx +++ b/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action_button.tsx @@ -25,6 +25,7 @@ const AddToCaseActionButtonComponent: React.FC = ({ useInsertTimeline, casePermissions, appId, + owner, onClose, }) => { const { @@ -36,7 +37,7 @@ const AddToCaseActionButtonComponent: React.FC = ({ openPopover, closePopover, isPopoverOpen, - } = useAddToCase({ event, useInsertTimeline, casePermissions, appId, onClose }); + } = useAddToCase({ event, useInsertTimeline, casePermissions, appId, owner, onClose }); const tooltipContext = userCanCrud ? isEventSupported ? i18n.ACTION_ADD_TO_CASE_TOOLTIP diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_existing_case_button.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_existing_case_button.tsx index 30181a96aa70b..a1fdfe1e8dfa7 100644 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_existing_case_button.tsx +++ b/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_existing_case_button.tsx @@ -18,6 +18,7 @@ const AddToCaseActionComponent: React.FC = ({ useInsertTimeline, casePermissions, appId, + owner, onClose, }) => { const { addExistingCaseClick, isDisabled, userCanCrud } = useAddToCase({ @@ -25,6 +26,7 @@ const AddToCaseActionComponent: React.FC = ({ useInsertTimeline, casePermissions, appId, + owner, onClose, }); return ( diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_new_case_button.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_new_case_button.tsx index 82ce3d1ff8dc8..5c4be89f56d88 100644 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_new_case_button.tsx +++ b/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_new_case_button.tsx @@ -18,6 +18,7 @@ const AddToCaseActionComponent: React.FC = ({ useInsertTimeline, casePermissions, appId, + owner, onClose, }) => { const { addNewCaseClick, isDisabled, userCanCrud } = useAddToCase({ @@ -25,6 +26,7 @@ const AddToCaseActionComponent: React.FC = ({ useInsertTimeline, casePermissions, appId, + owner, onClose, }); diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/create/flyout.test.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/create/flyout.test.tsx index bbfdef803493b..f1176f612725a 100644 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/create/flyout.test.tsx +++ b/x-pack/plugins/timelines/public/components/actions/timeline/cases/create/flyout.test.tsx @@ -16,7 +16,7 @@ const onSuccess = jest.fn(); const defaultProps = { onCloseFlyout, onSuccess, - appId: 'securitySolution', + owner: 'securitySolution', }; describe('CreateCaseFlyout', () => { diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/create/flyout.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/create/flyout.tsx index 727d853990224..c91c50c61fcf8 100644 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/create/flyout.tsx +++ b/x-pack/plugins/timelines/public/components/actions/timeline/cases/create/flyout.tsx @@ -19,7 +19,7 @@ export interface CreateCaseModalProps { onCloseFlyout: () => void; onSuccess: (theCase: Case) => Promise; useInsertTimeline?: Function; - appId: string; + owner: string; disableAlerts?: boolean; } @@ -70,7 +70,7 @@ const CreateCaseFlyoutComponent: React.FC = ({ afterCaseCreated, onCloseFlyout, onSuccess, - appId, + owner, disableAlerts, }) => { const { cases } = useKibana().services; @@ -80,10 +80,10 @@ const CreateCaseFlyoutComponent: React.FC = ({ onCancel: onCloseFlyout, onSuccess, withSteps: false, - owner: [appId], + owner: [owner], disableAlerts, }; - }, [afterCaseCreated, onCloseFlyout, onSuccess, appId, disableAlerts]); + }, [afterCaseCreated, onCloseFlyout, onSuccess, owner, disableAlerts]); return ( <> diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx index 29766a5b8a1f5..6b6b1cffec196 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx @@ -46,6 +46,7 @@ import { TimelineTabs, SetEventsLoading, SetEventsDeleted, + CreateFieldComponentType, } from '../../../../common/types/timeline'; import type { TimelineItem, TimelineNonEcsData } from '../../../../common/search_strategy/timeline'; @@ -86,6 +87,7 @@ interface OwnProps { additionalControls?: React.ReactNode; browserFields: BrowserFields; bulkActions?: BulkActionsProp; + createFieldComponent?: CreateFieldComponentType; data: TimelineItem[]; defaultCellActions?: TGridCellAction[]; filters?: Filter[]; @@ -160,6 +162,7 @@ const transformControlColumns = ({ actionColumnsWidth, columnHeaders, controlColumns, + createFieldComponent, data, isEventViewer = false, loadingEventIds, @@ -182,6 +185,7 @@ const transformControlColumns = ({ actionColumnsWidth: number; columnHeaders: ColumnHeaderOptions[]; controlColumns: ControlColumnProps[]; + createFieldComponent?: CreateFieldComponentType; data: TimelineItem[]; isEventViewer?: boolean; loadingEventIds: string[]; @@ -227,6 +231,7 @@ const transformControlColumns = ({ sort={sort} tabType={tabType} timelineId={timelineId} + createFieldComponent={createFieldComponent} /> )} @@ -308,6 +313,7 @@ export const BodyComponent = React.memo( bulkActions = true, clearSelected, columnHeaders, + createFieldComponent, data, defaultCellActions, filterQuery, @@ -491,6 +497,7 @@ export const BodyComponent = React.memo( @@ -527,6 +534,7 @@ export const BodyComponent = React.memo( additionalControls, browserFields, columnHeaders, + createFieldComponent, ] ); @@ -616,6 +624,7 @@ export const BodyComponent = React.memo( transformControlColumns({ columnHeaders, controlColumns, + createFieldComponent, data, isEventViewer, actionColumnsWidth: hasAdditionalActions(id as TimelineId) @@ -648,6 +657,7 @@ export const BodyComponent = React.memo( leadingControlColumns, trailingControlColumns, columnHeaders, + createFieldComponent, data, isEventViewer, id, diff --git a/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx index 614857c26cbb1..4716901ee256f 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx @@ -23,6 +23,7 @@ import type { CoreStart } from '../../../../../../../src/core/public'; import type { BrowserFields } from '../../../../common/search_strategy/index_fields'; import { BulkActionsProp, + CreateFieldComponentType, TGridCellAction, TimelineId, TimelineTabs, @@ -98,6 +99,7 @@ export interface TGridIntegratedProps { browserFields: BrowserFields; bulkActions?: BulkActionsProp; columns: ColumnHeaderOptions[]; + createFieldComponent?: CreateFieldComponentType; data?: DataPublicPluginStart; dataProviders: DataProvider[]; defaultCellActions?: TGridCellAction[]; @@ -152,6 +154,7 @@ const TGridIntegratedComponent: React.FC = ({ globalFullScreen, graphEventId, graphOverlay = null, + createFieldComponent, hasAlertsCrud, id, indexNames, @@ -349,6 +352,7 @@ const TGridIntegratedComponent: React.FC = ({ activePage={pageInfo.activePage} browserFields={browserFields} bulkActions={bulkActions} + createFieldComponent={createFieldComponent} data={nonDeletedEvents} defaultCellActions={defaultCellActions} filterQuery={filterQuery} diff --git a/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx index 4ae8e1e191d80..1cb13a9d6cbb9 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx @@ -80,6 +80,7 @@ const ScrollableFlexItem = styled(EuiFlexItem)` export interface TGridStandaloneProps { appId: string; + casesOwner: string; casePermissions: { crud: boolean; read: boolean; @@ -123,6 +124,7 @@ export interface TGridStandaloneProps { const TGridStandaloneComponent: React.FC = ({ afterCaseSelection, appId, + casesOwner, casePermissions, columns, defaultCellActions, @@ -275,9 +277,10 @@ const TGridStandaloneComponent: React.FC = ({ event: selectedEvent, casePermissions: casePermissions ?? null, appId, + owner: casesOwner, onClose: afterCaseSelection, }; - }, [appId, casePermissions, afterCaseSelection, selectedEvent]); + }, [appId, casePermissions, afterCaseSelection, selectedEvent, casesOwner]); const nonDeletedEvents = useMemo( () => events.filter((e) => !deletedEventIds.includes(e._id)), diff --git a/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/field_browser.test.tsx b/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/field_browser.test.tsx index e19499628e8c1..f819a93ae57c0 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/field_browser.test.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/field_browser.test.tsx @@ -271,4 +271,29 @@ describe('FieldsBrowser', () => { expect(onSearchInputChange).toBeCalledWith(inputText); }); + + test('it renders the CreateField button when createFieldComponent is provided', () => { + const MyTestComponent = () =>
{'test'}
; + + const wrapper = mount( + + ()} + selectedCategoryId={''} + timelineId={timelineId} + createFieldComponent={MyTestComponent} + /> + + ); + + expect(wrapper.find(MyTestComponent).exists()).toBeTruthy(); + }); }); diff --git a/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/field_browser.tsx b/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/field_browser.tsx index a645235b620d8..b7f72e66b1a87 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/field_browser.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/field_browser.tsx @@ -21,11 +21,16 @@ import React, { useEffect, useCallback, useRef, useMemo } from 'react'; import styled from 'styled-components'; import { useDispatch } from 'react-redux'; -import type { BrowserFields, ColumnHeaderOptions } from '../../../../../common'; +import type { + BrowserFields, + ColumnHeaderOptions, + CreateFieldComponentType, +} from '../../../../../common'; import { isEscape, isTab, stopPropagationAndPreventDefault } from '../../../../../common'; import { CategoriesPane } from './categories_pane'; import { FieldsPane } from './fields_pane'; import { Search } from './search'; + import { CATEGORY_PANE_WIDTH, CLOSE_BUTTON_CLASS_NAME, @@ -53,6 +58,9 @@ type Props = Pick & * The current timeline column headers */ columnHeaders: ColumnHeaderOptions[]; + + createFieldComponent?: CreateFieldComponentType; + /** * A map of categoryId -> metadata about the fields in that category, * filtered such that the name of every field in the category includes @@ -99,6 +107,7 @@ type Props = Pick & const FieldsBrowserComponent: React.FC = ({ columnHeaders, filteredBrowserFields, + createFieldComponent: CreateField, isSearching, onCategorySelected, onSearchInputChange, @@ -187,14 +196,22 @@ const FieldsBrowserComponent: React.FC = ({ - + + + + + + {CreateField && } + + + diff --git a/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/index.tsx index 0b67f53cca76e..abe882d9a8b59 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/index.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/index.tsx @@ -34,6 +34,7 @@ export const StatefulFieldsBrowserComponent: React.FC = ({ timelineId, columnHeaders, browserFields, + createFieldComponent, width, }) => { const customizeColumnsButtonRef = useRef(null); @@ -140,6 +141,7 @@ export const StatefulFieldsBrowserComponent: React.FC = ({ {show && ( metadata about the fields in that category */ browserFields: BrowserFields; + + createFieldComponent?: CreateFieldComponentType; /** When true, this Fields Browser is being used as an "events viewer" */ isEventViewer?: boolean; /** The width of the field browser */ diff --git a/x-pack/plugins/timelines/public/components/t_grid/translations.ts b/x-pack/plugins/timelines/public/components/t_grid/translations.ts index 6d440a5fbb375..1848026d14b66 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/translations.ts +++ b/x-pack/plugins/timelines/public/components/t_grid/translations.ts @@ -22,7 +22,7 @@ export const EVENTS_TABLE_ARIA_LABEL = ({ export const BULK_ACTION_OPEN_SELECTED = i18n.translate( 'xpack.timelines.timeline.openSelectedTitle', { - defaultMessage: 'Open selected', + defaultMessage: 'Mark as open', } ); diff --git a/x-pack/plugins/timelines/public/hooks/use_add_to_case.ts b/x-pack/plugins/timelines/public/hooks/use_add_to_case.ts index 34622423781f9..a9804eb1277c9 100644 --- a/x-pack/plugins/timelines/public/hooks/use_add_to_case.ts +++ b/x-pack/plugins/timelines/public/hooks/use_add_to_case.ts @@ -81,6 +81,7 @@ export const useAddToCase = ({ useInsertTimeline, casePermissions, appId, + owner, onClose, }: AddToCaseActionProps): UseAddToCase => { const eventId = event?.ecs._id ?? ''; @@ -167,13 +168,13 @@ export const useAddToCase = ({ id: ruleId, name: ruleName, }, - owner: appId, + owner, }, updateCase, }); } }, - [eventId, eventIndex, appId, dispatch, event] + [eventId, eventIndex, owner, dispatch, event] ); const onCaseSuccess = useCallback( async (theCase: Case) => { @@ -187,7 +188,7 @@ export const useAddToCase = ({ async (ev) => { ev.preventDefault(); return navigateToApp(appId, { - deepLinkId: appId === 'securitySolution' ? 'case' : 'cases', + deepLinkId: appId === 'securitySolutionUI' ? 'case' : 'cases', path: getCreateCaseUrl(urlSearch), }); }, diff --git a/x-pack/plugins/timelines/public/index.ts b/x-pack/plugins/timelines/public/index.ts index 040137a9ea545..23252eeebc4cf 100644 --- a/x-pack/plugins/timelines/public/index.ts +++ b/x-pack/plugins/timelines/public/index.ts @@ -67,3 +67,5 @@ export function plugin() { export const StatefulEventContext = createContext(null); export { TimelineContext } from './components/t_grid/shared'; + +export type { CreateFieldComponentType } from '../common'; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index c8ad3bad75ef3..d96657d7a0c88 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -4825,20 +4825,14 @@ "visTypeMetric.schemas.metricTitle": "メトリック", "visTypeMetric.schemas.splitGroupTitle": "グループを分割", "expressionMetricVis.function.dimension.splitGroup": "グループを分割", - "expressionMetricVis.function.bgFill.help": "html 16 進数コード(#123456)、html 色(red、blue)、または rgba 値(rgba(255,255,255,1))。", "expressionMetricVis.function.bucket.help": "バケットディメンションの構成です。", "expressionMetricVis.function.colorMode.help": "色を変更するメトリックの部分", - "expressionMetricVis.function.colorRange.help": "別の色が適用される値のグループを指定する範囲オブジェクト。", - "expressionMetricVis.function.colorSchema.help": "使用する配色", "expressionMetricVis.function.dimension.metric": "メトリック", "expressionMetricVis.function.font.help": "フォント設定です。", "expressionMetricVis.function.help": "メトリックビジュアライゼーション", - "expressionMetricVis.function.invertColors.help": "色範囲を反転します", "expressionMetricVis.function.metric.help": "メトリックディメンションの構成です。", "expressionMetricVis.function.percentageMode.help": "百分率モードでメトリックを表示します。colorRange を設定する必要があります。", "expressionMetricVis.function.showLabels.help": "メトリック値の下にラベルを表示します。", - "expressionMetricVis.function.subText.help": "メトリックの下に表示するカスタムテキスト", - "expressionMetricVis.function.useRanges.help": "有効な色範囲です。", "visTypePie.advancedSettings.visualization.legacyPieChartsLibrary.deprecation": "Visualizeの円グラフのレガシーグラフライブラリは廃止予定であり、8.0以降ではサポートされません。", "visTypePie.advancedSettings.visualization.legacyPieChartsLibrary.description": "Visualizeで円グラフのレガシーグラフライブラリを有効にします。", "visTypePie.advancedSettings.visualization.legacyPieChartsLibrary.name": "円グラフのレガシーグラフライブラリ", @@ -9741,7 +9735,6 @@ "xpack.enterpriseSearch.appSearch.logRetention.callout.disabledSinceTitle": "{logsTitle}は、{disabledDate}以降に無効にされました。", "xpack.enterpriseSearch.appSearch.logRetention.callout.disabledTitle": "{logsTitle}は無効です。", "xpack.enterpriseSearch.appSearch.logRetention.customPolicy": "カスタム{logsType}ログ保持ポリシーがあります。", - "xpack.enterpriseSearch.appSearch.logRetention.ilmDisabled": "App Search は{logsType}ログ保持を管理していません。", "xpack.enterpriseSearch.appSearch.logRetention.noLogging": "すべてのエンジンの{logsType}ログが無効です。", "xpack.enterpriseSearch.appSearch.logRetention.noLogging.collected": "前回の{logsType}ログは{disabledAtDate}に収集されました。", "xpack.enterpriseSearch.appSearch.logRetention.noLogging.notCollected": "収集された{logsType}ログはありません。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 2787d971d3f1d..e1e77cae2fbd1 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -4868,20 +4868,14 @@ "visTypeMetric.schemas.metricTitle": "指标", "visTypeMetric.schemas.splitGroupTitle": "拆分组", "expressionMetricVis.function.dimension.splitGroup": "拆分组", - "expressionMetricVis.function.bgFill.help": "将颜色表示为 html 十六进制代码 (#123456)、html 颜色(red、blue)或 rgba 值 (rgba(255,255,255,1))。", "expressionMetricVis.function.bucket.help": "存储桶维度配置", "expressionMetricVis.function.colorMode.help": "指标的哪部分要上色", - "expressionMetricVis.function.colorRange.help": "指定应将不同颜色应用到的值组的范围对象。", - "expressionMetricVis.function.colorSchema.help": "要使用的颜色方案", "expressionMetricVis.function.dimension.metric": "指标", "expressionMetricVis.function.font.help": "字体设置。", "expressionMetricVis.function.help": "指标可视化", - "expressionMetricVis.function.invertColors.help": "反转颜色范围", "expressionMetricVis.function.metric.help": "指标维度配置", "expressionMetricVis.function.percentageMode.help": "以百分比模式显示指标。需要设置 colorRange。", "expressionMetricVis.function.showLabels.help": "在指标值下显示标签。", - "expressionMetricVis.function.subText.help": "要在指标下显示的定制文本", - "expressionMetricVis.function.useRanges.help": "已启用颜色范围。", "visTypePie.advancedSettings.visualization.legacyPieChartsLibrary.deprecation": "Visualize 中饼图的旧版图表库已弃用,自 8.0 后将不受支持。", "visTypePie.advancedSettings.visualization.legacyPieChartsLibrary.description": "在 Visualize 中启用饼图的旧版图表库。", "visTypePie.advancedSettings.visualization.legacyPieChartsLibrary.name": "饼图旧版图表库", @@ -9839,7 +9833,6 @@ "xpack.enterpriseSearch.appSearch.logRetention.callout.disabledTitle": "{logsTitle} 已禁用。", "xpack.enterpriseSearch.appSearch.logRetention.customPolicy": "您有定制 {logsType} 日志保留策略。", "xpack.enterpriseSearch.appSearch.logRetention.defaultPolicy": "您的 {logsType} 日志将存储至少 {minAgeDays, plural, other {# 天}}。", - "xpack.enterpriseSearch.appSearch.logRetention.ilmDisabled": "App Search 未管理 {logsType} 日志保留。", "xpack.enterpriseSearch.appSearch.logRetention.noLogging": "所有引擎的 {logsType} 日志记录均已禁用。", "xpack.enterpriseSearch.appSearch.logRetention.noLogging.collected": "{logsType} 日志的最后收集日期为 {disabledAtDate}。", "xpack.enterpriseSearch.appSearch.logRetention.noLogging.notCollected": "未收集任何 {logsType} 日志。", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/index.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/index.ts index d9bad9677c6b8..a58dd84e9a32b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/index.ts @@ -22,8 +22,6 @@ import { import { getJiraActionType } from './jira'; import { getResilientActionType } from './resilient'; import { getTeamsActionType } from './teams'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ENABLE_ITOM } from '../../../../../actions/server/constants/connectors'; export function registerBuiltInActionTypes({ actionTypeRegistry, @@ -38,13 +36,9 @@ export function registerBuiltInActionTypes({ actionTypeRegistry.register(getSwimlaneActionType()); actionTypeRegistry.register(getWebhookActionType()); actionTypeRegistry.register(getServiceNowITSMActionType()); + actionTypeRegistry.register(getServiceNowITOMActionType()); actionTypeRegistry.register(getServiceNowSIRActionType()); actionTypeRegistry.register(getJiraActionType()); actionTypeRegistry.register(getResilientActionType()); actionTypeRegistry.register(getTeamsActionType()); - - // TODO: Remove when ITOM is ready - if (ENABLE_ITOM) { - actionTypeRegistry.register(getServiceNowITOMActionType()); - } } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.test.ts index 525430ea7fc64..9a8094f53d501 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.test.ts @@ -50,8 +50,49 @@ describe('helpers', () => { }); describe('isDeprecatedConnector', () => { + const connector = { + id: 'test', + actionTypeId: '.webhook', + name: 'Test', + config: { apiUrl: 'http://example.com', usesTableApi: false }, + secrets: { username: 'test', password: 'test' }, + isPreconfigured: false as const, + }; + it('returns false if the connector is not defined', () => { expect(isDeprecatedConnector()).toBe(false); }); + + it('returns false if the connector is not ITSM or SecOps', () => { + expect(isDeprecatedConnector(connector)).toBe(false); + }); + + it('returns false if the connector is .servicenow and the usesTableApi=false', () => { + expect(isDeprecatedConnector({ ...connector, actionTypeId: '.servicenow' })).toBe(false); + }); + + it('returns false if the connector is .servicenow-sir and the usesTableApi=false', () => { + expect(isDeprecatedConnector({ ...connector, actionTypeId: '.servicenow-sir' })).toBe(false); + }); + + it('returns true if the connector is .servicenow and the usesTableApi=true', () => { + expect( + isDeprecatedConnector({ + ...connector, + actionTypeId: '.servicenow', + config: { ...connector.config, usesTableApi: true }, + }) + ).toBe(true); + }); + + it('returns true if the connector is .servicenow-sir and the usesTableApi=true', () => { + expect( + isDeprecatedConnector({ + ...connector, + actionTypeId: '.servicenow-sir', + config: { ...connector.config, usesTableApi: true }, + }) + ).toBe(true); + }); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts index 7274c59527415..de0b30b9acb2f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts @@ -6,11 +6,6 @@ */ import { EuiSelectOption } from '@elastic/eui'; -import { - ENABLE_NEW_SN_ITSM_CONNECTOR, - ENABLE_NEW_SN_SIR_CONNECTOR, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../../actions/server/constants/connectors'; import { IErrorObject } from '../../../../../public/types'; import { AppInfo, Choice, RESTApiError, ServiceNowActionConnector } from './types'; @@ -33,22 +28,16 @@ export const isDeprecatedConnector = (connector?: ServiceNowActionConnector): bo return false; } - if (!ENABLE_NEW_SN_ITSM_CONNECTOR && connector.actionTypeId === '.servicenow') { - return true; + if (connector.actionTypeId === '.servicenow' || connector.actionTypeId === '.servicenow-sir') { + /** + * Connector's prior to the Elastic ServiceNow application + * use the Table API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_TableAPI) + * Connectors after the Elastic ServiceNow application use the + * Import Set API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_ImportSetAPI) + * A ServiceNow connector is considered deprecated if it uses the Table API. + */ + return !!connector.config.usesTableApi; } - if (!ENABLE_NEW_SN_SIR_CONNECTOR && connector.actionTypeId === '.servicenow-sir') { - return true; - } - - /** - * Connectors after the Elastic ServiceNow application use the - * Import Set API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_ImportSetAPI) - * A ServiceNow connector is considered deprecated if it uses the Table API. - * - * All other connectors do not have the usesTableApi config property - * so the function will always return false for them. - */ - - return !!connector.config.usesTableApi; + return false; }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx index 90eadaf5f9b8b..d477fcd0ddf74 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx @@ -6,6 +6,8 @@ */ import * as React from 'react'; +// eslint-disable-next-line @kbn/eslint/module_migration +import { ThemeProvider } from 'styled-components'; import { mountWithIntl, nextTick } from '@kbn/test/jest'; import ActionsConnectorsList from './actions_connectors_list'; @@ -458,3 +460,80 @@ describe('actions_connectors_list component with disabled items', () => { ); }); }); + +describe('actions_connectors_list component with deprecated connectors', () => { + let wrapper: ReactWrapper; + + async function setup() { + loadAllActions.mockResolvedValueOnce([ + { + id: '1', + actionTypeId: '.servicenow', + description: 'My test', + referencedByCount: 1, + config: { usesTableApi: true }, + }, + { + id: '2', + actionTypeId: '.servicenow-sir', + description: 'My test 2', + referencedByCount: 1, + config: { usesTableApi: true }, + }, + ]); + loadActionTypes.mockResolvedValueOnce([ + { + id: 'test', + name: '.servicenow', + enabled: false, + enabledInConfig: false, + enabledInLicense: true, + }, + { + id: 'test2', + name: '.servicenow-sir', + enabled: false, + enabledInConfig: true, + enabledInLicense: false, + }, + ]); + + const [ + { + application: { capabilities }, + }, + ] = await mocks.getStartServices(); + + // eslint-disable-next-line react-hooks/rules-of-hooks + useKibanaMock().services.application.capabilities = { + ...capabilities, + actions: { + show: true, + save: true, + delete: true, + }, + }; + // eslint-disable-next-line react-hooks/rules-of-hooks + useKibanaMock().services.actionTypeRegistry = actionTypeRegistry; + wrapper = mountWithIntl( + ({ eui: { euiSizeS: '15px' }, darkMode: true })}> + + + ); + + // Wait for active space to resolve before requesting the component to update + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(loadAllActions).toHaveBeenCalled(); + } + + it('shows the warning icon', async () => { + await setup(); + expect(wrapper.find('EuiInMemoryTable')).toHaveLength(1); + expect(wrapper.find('EuiTableRow')).toHaveLength(2); + expect(wrapper.find('.euiToolTipAnchor [aria-label="Warning"]').exists()).toBe(true); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx index 5de21470fc19a..6b52479f2ac87 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx @@ -48,11 +48,6 @@ import { DEFAULT_HIDDEN_ACTION_TYPES } from '../../../../'; import { CenterJustifiedSpinner } from '../../../components/center_justified_spinner'; import ConnectorEditFlyout from '../../action_connector_form/connector_edit_flyout'; import ConnectorAddFlyout from '../../action_connector_form/connector_add_flyout'; -import { - ENABLE_NEW_SN_ITSM_CONNECTOR, - ENABLE_NEW_SN_SIR_CONNECTOR, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../../actions/server/constants/connectors'; const ConnectorIconTipWithSpacing = withTheme(({ theme }: { theme: EuiTheme }) => { return ( @@ -202,14 +197,19 @@ const ActionsConnectorsList: React.FunctionComponent = () => { const checkEnabledResult = checkActionTypeEnabled( actionTypesIndex && actionTypesIndex[item.actionTypeId] ); + const itemConfig = ( item as UserConfiguredActionConnector, Record> ).config; - const showDeprecatedTooltip = - itemConfig?.usesTableApi && - // TODO: Remove when applications are certified - ((ENABLE_NEW_SN_ITSM_CONNECTOR && item.actionTypeId === '.servicenow') || - (ENABLE_NEW_SN_SIR_CONNECTOR && item.actionTypeId === '.servicenow-sir')); + + /** + * TODO: Remove when connectors can provide their own UX message. + * Issue: https://github.com/elastic/kibana/issues/114507 + */ + const hasSNApplication = + item?.actionTypeId === '.servicenow' || item?.actionTypeId === '.servicenow-sir'; + + const showDeprecatedTooltip = hasSNApplication && itemConfig?.usesTableApi; const link = ( <> diff --git a/x-pack/test/api_integration/apis/maps/migrations.js b/x-pack/test/api_integration/apis/maps/migrations.js index f8b603ac38fde..19f79da940253 100644 --- a/x-pack/test/api_integration/apis/maps/migrations.js +++ b/x-pack/test/api_integration/apis/maps/migrations.js @@ -11,7 +11,7 @@ export default function ({ getService }) { const supertest = getService('supertest'); const kibanaServer = getService('kibanaServer'); - describe('migrations', () => { + describe('map migrations', () => { describe('saved object migrations', () => { it('should apply saved object reference migration when importing map saved objects prior to 7.2.0', async () => { const resp = await supertest @@ -47,6 +47,20 @@ export default function ({ getService }) { expect(resp.body.migrationVersion).to.eql({ map: '8.0.0' }); // migrtionVersion is derived from both "migrations" and "convertToMultiNamespaceVersion" fields when the object is registered expect(resp.body.attributes.layerListJSON.includes('indexPatternRefName')).to.be(true); }); + + it('should not fail migration with invalid attributes', async () => { + await supertest + .post(`/api/saved_objects/map`) + .set('kbn-xsrf', 'kibana') + .send({ + attributes: { + title: '[Logs] Total Requests and Bytes', + layerListJSON: 'not valid layerListJSON', + }, + migrationVersion: {}, + }) + .expect(200); + }); }); describe('embeddable migrations', () => { diff --git a/x-pack/test/apm_api_integration/common/config.ts b/x-pack/test/apm_api_integration/common/config.ts index ab22522acac52..cee1fdbbc50b3 100644 --- a/x-pack/test/apm_api_integration/common/config.ts +++ b/x-pack/test/apm_api_integration/common/config.ts @@ -14,10 +14,10 @@ import { PromiseReturnType } from '../../../plugins/observability/typings/common import { createApmUser, APM_TEST_PASSWORD, ApmUser } from './authentication'; import { APMFtrConfigName } from '../configs'; import { createApmApiClient } from './apm_api_supertest'; -import { registry } from './registry'; +import { RegistryProvider } from './registry'; import { synthtraceEsClientService } from './synthtrace_es_client_service'; -interface Config { +export interface ApmFtrConfig { name: APMFtrConfigName; license: 'basic' | 'trial'; kibanaConfig?: Record; @@ -58,7 +58,7 @@ async function getApmApiClient( export type CreateTestConfig = ReturnType; -export function createTestConfig(config: Config) { +export function createTestConfig(config: ApmFtrConfig) { const { license, name, kibanaConfig } = config; return async ({ readConfigFile }: FtrConfigProviderContext) => { @@ -70,13 +70,14 @@ export function createTestConfig(config: Config) { const servers = xPackAPITestsConfig.get('servers'); const kibanaServer = servers.kibana; - registry.init(config.name); - return { testFiles: [require.resolve('../tests')], servers, + servicesRequiredForTestAnalysis: ['apmFtrConfig', 'registry'], services: { ...services, + apmFtrConfig: () => config, + registry: RegistryProvider, synthtraceEsClient: synthtraceEsClientService, apmApiClient: async (context: InheritedFtrProviderContext) => { const security = context.getService('security'); diff --git a/x-pack/test/apm_api_integration/common/registry.ts b/x-pack/test/apm_api_integration/common/registry.ts index 55b5863e6d444..ac59059e49d83 100644 --- a/x-pack/test/apm_api_integration/common/registry.ts +++ b/x-pack/test/apm_api_integration/common/registry.ts @@ -28,168 +28,165 @@ interface RunCondition { archives: ArchiveName[]; } -const callbacks: Array< - RunCondition & { - runs: Array<{ - cb: () => void; - }>; - } -> = []; +export function RegistryProvider({ getService }: FtrProviderContext) { + const apmFtrConfig = getService('apmFtrConfig'); + + const callbacks: Array< + RunCondition & { + runs: Array<{ + cb: () => void; + }>; + } + > = []; -let configName: APMFtrConfigName | undefined; + let running: boolean = false; -let running: boolean = false; + function when( + title: string, + conditions: RunCondition | RunCondition[], + callback: (condition: RunCondition) => void, + skip?: boolean + ) { + const allConditions = castArray(conditions); -function when( - title: string, - conditions: RunCondition | RunCondition[], - callback: (condition: RunCondition) => void, - skip?: boolean -) { - const allConditions = castArray(conditions); + if (!allConditions.length) { + throw new Error('At least one condition should be defined'); + } - if (!allConditions.length) { - throw new Error('At least one condition should be defined'); - } + if (running) { + throw new Error("Can't add tests when running"); + } - if (running) { - throw new Error("Can't add tests when running"); - } + const frame = maybe(callsites()[1]); - const frame = maybe(callsites()[1]); + const file = frame?.getFileName(); - const file = frame?.getFileName(); + if (!file) { + throw new Error('Could not infer file for suite'); + } - if (!file) { - throw new Error('Could not infer file for suite'); + allConditions.forEach((matchedCondition) => { + callbacks.push({ + ...matchedCondition, + runs: [ + { + cb: () => { + const suite: ReturnType = (skip ? describe.skip : describe)( + title, + () => { + callback(matchedCondition); + } + ) as any; + + suite.file = file; + suite.eachTest((test) => { + test.file = file; + }); + }, + }, + ], + }); + }); } - allConditions.forEach((matchedCondition) => { - callbacks.push({ - ...matchedCondition, - runs: [ - { - cb: () => { - const suite: ReturnType = (skip ? describe.skip : describe)( - title, - () => { - callback(matchedCondition); - } - ) as any; + when.skip = ( + title: string, + conditions: RunCondition | RunCondition[], + callback: (condition: RunCondition) => void + ) => { + when(title, conditions, callback, true); + }; - suite.file = file; - suite.eachTest((test) => { - test.file = file; - }); - }, - }, - ], - }); - }); -} + const registry = { + when, + run: () => { + running = true; -when.skip = ( - title: string, - conditions: RunCondition | RunCondition[], - callback: (condition: RunCondition) => void -) => { - when(title, conditions, callback, true); -}; - -export const registry = { - init: (config: APMFtrConfigName) => { - configName = config; - callbacks.length = 0; - running = false; - }, - when, - run: (context: FtrProviderContext) => { - if (!configName) { - throw new Error(`registry was not init() before running`); - } - running = true; - const esArchiver = context.getService('esArchiver'); - const logger = context.getService('log'); + const esArchiver = getService('esArchiver'); + const logger = getService('log'); - const supertest = context.getService('legacySupertestAsApmWriteUser'); + const supertest = getService('legacySupertestAsApmWriteUser'); - const logWithTimer = () => { - const start = process.hrtime(); + const logWithTimer = () => { + const start = process.hrtime(); - return (message: string) => { - const diff = process.hrtime(start); - const time = `${Math.round(diff[0] * 1000 + diff[1] / 1e6)}ms`; - logger.info(`(${time}) ${message}`); + return (message: string) => { + const diff = process.hrtime(start); + const time = `${Math.round(diff[0] * 1000 + diff[1] / 1e6)}ms`; + logger.info(`(${time}) ${message}`); + }; }; - }; - - const groups = joinByKey(callbacks, ['config', 'archives'], (a, b) => ({ - ...a, - ...b, - runs: a.runs.concat(b.runs), - })); - - callbacks.length = 0; - - const byConfig = groupBy(groups, 'config'); - - Object.keys(byConfig).forEach((config) => { - const groupsForConfig = byConfig[config]; - // register suites for other configs, but skip them so tests are marked as such - // and their snapshots are not marked as obsolete - (config === configName ? describe : describe.skip)(config, () => { - groupsForConfig.forEach((group) => { - const { runs, ...condition } = group; - - const runBefore = async () => { - const log = logWithTimer(); - for (const archiveName of condition.archives) { - log(`Loading ${archiveName}`); - - await esArchiver.load( - Path.join( - 'x-pack/test/apm_api_integration/common/fixtures/es_archiver', - archiveName - ) - ); - - // sync jobs from .ml-config to .kibana SOs - await supertest.get('/api/ml/saved_objects/sync').set('kbn-xsrf', 'foo'); - } - if (condition.archives.length) { - log('Loaded all archives'); - } - }; - - const runAfter = async () => { - const log = logWithTimer(); - for (const archiveName of condition.archives) { - log(`Unloading ${archiveName}`); - await esArchiver.unload( - Path.join( - 'x-pack/test/apm_api_integration/common/fixtures/es_archiver', - archiveName - ) - ); - } - if (condition.archives.length) { - log('Unloaded all archives'); - } - }; - - describe(condition.archives.join(',') || 'no data', () => { - before(runBefore); - - runs.forEach((run) => { - run.cb(); - }); - after(runAfter); + const groups = joinByKey(callbacks, ['config', 'archives'], (a, b) => ({ + ...a, + ...b, + runs: a.runs.concat(b.runs), + })); + + callbacks.length = 0; + + const byConfig = groupBy(groups, 'config'); + + Object.keys(byConfig).forEach((config) => { + const groupsForConfig = byConfig[config]; + // register suites for other configs, but skip them so tests are marked as such + // and their snapshots are not marked as obsolete + (config === apmFtrConfig.name ? describe : describe.skip)(config, () => { + groupsForConfig.forEach((group) => { + const { runs, ...condition } = group; + + const runBefore = async () => { + const log = logWithTimer(); + for (const archiveName of condition.archives) { + log(`Loading ${archiveName}`); + + await esArchiver.load( + Path.join( + 'x-pack/test/apm_api_integration/common/fixtures/es_archiver', + archiveName + ) + ); + + // sync jobs from .ml-config to .kibana SOs + await supertest.get('/api/ml/saved_objects/sync').set('kbn-xsrf', 'foo'); + } + if (condition.archives.length) { + log('Loaded all archives'); + } + }; + + const runAfter = async () => { + const log = logWithTimer(); + for (const archiveName of condition.archives) { + log(`Unloading ${archiveName}`); + await esArchiver.unload( + Path.join( + 'x-pack/test/apm_api_integration/common/fixtures/es_archiver', + archiveName + ) + ); + } + if (condition.archives.length) { + log('Unloaded all archives'); + } + }; + + describe(condition.archives.join(',') || 'no data', () => { + before(runBefore); + + runs.forEach((run) => { + run.cb(); + }); + + after(runAfter); + }); }); }); }); - }); - running = false; - }, -}; + running = false; + }, + }; + + return registry; +} diff --git a/x-pack/test/apm_api_integration/tests/alerts/chart_preview.ts b/x-pack/test/apm_api_integration/tests/alerts/chart_preview.spec.ts similarity index 98% rename from x-pack/test/apm_api_integration/tests/alerts/chart_preview.ts rename to x-pack/test/apm_api_integration/tests/alerts/chart_preview.spec.ts index 621ed5dcfd8d7..63fe4fc67641a 100644 --- a/x-pack/test/apm_api_integration/tests/alerts/chart_preview.ts +++ b/x-pack/test/apm_api_integration/tests/alerts/chart_preview.spec.ts @@ -8,9 +8,9 @@ import expect from '@kbn/expect'; import archives from '../../common/fixtures/es_archiver/archives_metadata'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const archiveName = 'apm_8.0.0'; const { end } = archives[archiveName]; diff --git a/x-pack/test/apm_api_integration/tests/alerts/rule_registry.ts b/x-pack/test/apm_api_integration/tests/alerts/rule_registry.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/alerts/rule_registry.ts rename to x-pack/test/apm_api_integration/tests/alerts/rule_registry.spec.ts index 06abeb02404c8..efa8aa3ace9dc 100644 --- a/x-pack/test/apm_api_integration/tests/alerts/rule_registry.ts +++ b/x-pack/test/apm_api_integration/tests/alerts/rule_registry.spec.ts @@ -18,7 +18,6 @@ import { } from '@kbn/rule-data-utils'; import { merge, omit } from 'lodash'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; interface Alert { schedule: { @@ -36,6 +35,7 @@ interface Alert { } export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmWriteUser'); const es = getService('es'); diff --git a/x-pack/test/apm_api_integration/tests/correlations/failed_transactions.ts b/x-pack/test/apm_api_integration/tests/correlations/failed_transactions.spec.ts similarity index 97% rename from x-pack/test/apm_api_integration/tests/correlations/failed_transactions.ts rename to x-pack/test/apm_api_integration/tests/correlations/failed_transactions.spec.ts index 3388d5b4aa379..a20852ef0ae54 100644 --- a/x-pack/test/apm_api_integration/tests/correlations/failed_transactions.ts +++ b/x-pack/test/apm_api_integration/tests/correlations/failed_transactions.spec.ts @@ -14,10 +14,10 @@ import type { RawSearchStrategyClientParams } from '../../../../plugins/apm/comm import { APM_SEARCH_STRATEGIES } from '../../../../plugins/apm/common/search_strategies/constants'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; import { parseBfetchResponse } from '../../common/utils/parse_b_fetch'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const retry = getService('retry'); const supertest = getService('legacySupertestAsApmReadUser'); @@ -45,7 +45,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { }; registry.when('failed transactions without data', { config: 'trial', archives: [] }, () => { - it('queries the search strategy and returns results', async () => { + it.skip('queries the search strategy and returns results', async () => { const intialResponse = await supertest .post(`/internal/bsearch`) .set('kbn-xsrf', 'foo') @@ -134,7 +134,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); registry.when('failed transactions with data', { config: 'trial', archives: ['8.0.0'] }, () => { - it('queries the search strategy and returns results', async () => { + it.skip('queries the search strategy and returns results', async () => { const intialResponse = await supertest .post(`/internal/bsearch`) .set('kbn-xsrf', 'foo') diff --git a/x-pack/test/apm_api_integration/tests/correlations/latency.ts b/x-pack/test/apm_api_integration/tests/correlations/latency.spec.ts similarity index 98% rename from x-pack/test/apm_api_integration/tests/correlations/latency.ts rename to x-pack/test/apm_api_integration/tests/correlations/latency.spec.ts index 75a4edd447c70..8d768f559fb6d 100644 --- a/x-pack/test/apm_api_integration/tests/correlations/latency.ts +++ b/x-pack/test/apm_api_integration/tests/correlations/latency.spec.ts @@ -14,10 +14,10 @@ import type { RawSearchStrategyClientParams } from '../../../../plugins/apm/comm import { APM_SEARCH_STRATEGIES } from '../../../../plugins/apm/common/search_strategies/constants'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; import { parseBfetchResponse } from '../../common/utils/parse_b_fetch'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const retry = getService('retry'); const supertest = getService('legacySupertestAsApmReadUser'); @@ -144,7 +144,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { { config: 'trial', archives: ['8.0.0'] }, () => { // putting this into a single `it` because the responses depend on each other - it('queries the search strategy and returns results', async () => { + it.skip('queries the search strategy and returns results', async () => { const intialResponse = await supertest .post(`/internal/bsearch`) .set('kbn-xsrf', 'foo') diff --git a/x-pack/test/apm_api_integration/tests/csm/__snapshots__/page_load_dist.snap b/x-pack/test/apm_api_integration/tests/csm/__snapshots__/page_load_dist.spec.snap similarity index 100% rename from x-pack/test/apm_api_integration/tests/csm/__snapshots__/page_load_dist.snap rename to x-pack/test/apm_api_integration/tests/csm/__snapshots__/page_load_dist.spec.snap diff --git a/x-pack/test/apm_api_integration/tests/csm/__snapshots__/page_views.snap b/x-pack/test/apm_api_integration/tests/csm/__snapshots__/page_views.spec.snap similarity index 100% rename from x-pack/test/apm_api_integration/tests/csm/__snapshots__/page_views.snap rename to x-pack/test/apm_api_integration/tests/csm/__snapshots__/page_views.spec.snap diff --git a/x-pack/test/apm_api_integration/tests/csm/csm_services.ts b/x-pack/test/apm_api_integration/tests/csm/csm_services.spec.ts similarity index 96% rename from x-pack/test/apm_api_integration/tests/csm/csm_services.ts rename to x-pack/test/apm_api_integration/tests/csm/csm_services.spec.ts index 832ef93e3f721..2d5f0ddf1cd4c 100644 --- a/x-pack/test/apm_api_integration/tests/csm/csm_services.ts +++ b/x-pack/test/apm_api_integration/tests/csm/csm_services.spec.ts @@ -7,9 +7,9 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function rumServicesApiTests({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); registry.when('CSM Services without data', { config: 'trial', archives: [] }, () => { diff --git a/x-pack/test/apm_api_integration/tests/csm/has_rum_data.ts b/x-pack/test/apm_api_integration/tests/csm/has_rum_data.spec.ts similarity index 97% rename from x-pack/test/apm_api_integration/tests/csm/has_rum_data.ts rename to x-pack/test/apm_api_integration/tests/csm/has_rum_data.spec.ts index 3372e43396ed0..f9ba588ffccdb 100644 --- a/x-pack/test/apm_api_integration/tests/csm/has_rum_data.ts +++ b/x-pack/test/apm_api_integration/tests/csm/has_rum_data.spec.ts @@ -7,9 +7,9 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function rumHasDataApiTests({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); registry.when('has_rum_data without data', { config: 'trial', archives: [] }, () => { diff --git a/x-pack/test/apm_api_integration/tests/csm/js_errors.ts b/x-pack/test/apm_api_integration/tests/csm/js_errors.spec.ts similarity index 98% rename from x-pack/test/apm_api_integration/tests/csm/js_errors.ts rename to x-pack/test/apm_api_integration/tests/csm/js_errors.spec.ts index 6346c991373b5..5e4f306552273 100644 --- a/x-pack/test/apm_api_integration/tests/csm/js_errors.ts +++ b/x-pack/test/apm_api_integration/tests/csm/js_errors.spec.ts @@ -7,9 +7,9 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function rumJsErrorsApiTests({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); registry.when('CSM JS errors with data', { config: 'trial', archives: [] }, () => { diff --git a/x-pack/test/apm_api_integration/tests/csm/long_task_metrics.ts b/x-pack/test/apm_api_integration/tests/csm/long_task_metrics.spec.ts similarity index 97% rename from x-pack/test/apm_api_integration/tests/csm/long_task_metrics.ts rename to x-pack/test/apm_api_integration/tests/csm/long_task_metrics.spec.ts index 0cb84d1935fa8..ef1e537585b79 100644 --- a/x-pack/test/apm_api_integration/tests/csm/long_task_metrics.ts +++ b/x-pack/test/apm_api_integration/tests/csm/long_task_metrics.spec.ts @@ -7,9 +7,9 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function rumServicesApiTests({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); registry.when('CSM long task metrics without data', { config: 'trial', archives: [] }, () => { diff --git a/x-pack/test/apm_api_integration/tests/csm/page_load_dist.ts b/x-pack/test/apm_api_integration/tests/csm/page_load_dist.spec.ts similarity index 97% rename from x-pack/test/apm_api_integration/tests/csm/page_load_dist.ts rename to x-pack/test/apm_api_integration/tests/csm/page_load_dist.spec.ts index 8d6a38f27a8c4..1177b331c4c35 100644 --- a/x-pack/test/apm_api_integration/tests/csm/page_load_dist.ts +++ b/x-pack/test/apm_api_integration/tests/csm/page_load_dist.spec.ts @@ -7,9 +7,9 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function rumServicesApiTests({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); registry.when('UX page load dist without data', { config: 'trial', archives: [] }, () => { diff --git a/x-pack/test/apm_api_integration/tests/csm/page_views.ts b/x-pack/test/apm_api_integration/tests/csm/page_views.spec.ts similarity index 98% rename from x-pack/test/apm_api_integration/tests/csm/page_views.ts rename to x-pack/test/apm_api_integration/tests/csm/page_views.spec.ts index e5ffd37d3c682..40aa88aa5ad82 100644 --- a/x-pack/test/apm_api_integration/tests/csm/page_views.ts +++ b/x-pack/test/apm_api_integration/tests/csm/page_views.spec.ts @@ -7,9 +7,9 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function rumServicesApiTests({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); registry.when('CSM page views without data', { config: 'trial', archives: [] }, () => { diff --git a/x-pack/test/apm_api_integration/tests/csm/url_search.ts b/x-pack/test/apm_api_integration/tests/csm/url_search.spec.ts similarity index 98% rename from x-pack/test/apm_api_integration/tests/csm/url_search.ts rename to x-pack/test/apm_api_integration/tests/csm/url_search.spec.ts index 3c63186879788..f45e82865983e 100644 --- a/x-pack/test/apm_api_integration/tests/csm/url_search.ts +++ b/x-pack/test/apm_api_integration/tests/csm/url_search.spec.ts @@ -7,9 +7,9 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function rumServicesApiTests({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); registry.when('CSM url search api without data', { config: 'trial', archives: [] }, () => { diff --git a/x-pack/test/apm_api_integration/tests/csm/web_core_vitals.ts b/x-pack/test/apm_api_integration/tests/csm/web_core_vitals.spec.ts similarity index 97% rename from x-pack/test/apm_api_integration/tests/csm/web_core_vitals.ts rename to x-pack/test/apm_api_integration/tests/csm/web_core_vitals.spec.ts index 2c89b13d1b725..421bafcb4064f 100644 --- a/x-pack/test/apm_api_integration/tests/csm/web_core_vitals.ts +++ b/x-pack/test/apm_api_integration/tests/csm/web_core_vitals.spec.ts @@ -7,9 +7,9 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function rumServicesApiTests({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); registry.when('CSM web core vitals without data', { config: 'trial', archives: [] }, () => { diff --git a/x-pack/test/apm_api_integration/tests/dependencies/metadata.ts b/x-pack/test/apm_api_integration/tests/dependencies/metadata.spec.ts similarity index 95% rename from x-pack/test/apm_api_integration/tests/dependencies/metadata.ts rename to x-pack/test/apm_api_integration/tests/dependencies/metadata.spec.ts index 071370a8e6c73..89e79751cb7ec 100644 --- a/x-pack/test/apm_api_integration/tests/dependencies/metadata.ts +++ b/x-pack/test/apm_api_integration/tests/dependencies/metadata.spec.ts @@ -6,10 +6,10 @@ */ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; import { dataConfig, generateData } from './generate_data'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const synthtraceEsClient = getService('synthtraceEsClient'); @@ -46,6 +46,8 @@ export default function ApiTest({ getService }: FtrProviderContext) { 'Dependency metadata when data is generated', { config: 'basic', archives: ['apm_mappings_only_8.0.0'] }, () => { + after(() => synthtraceEsClient.clean()); + it('returns correct metadata for the dependency', async () => { await generateData({ synthtraceEsClient, start, end }); const { status, body } = await callApi(); diff --git a/x-pack/test/apm_api_integration/tests/dependencies/top_dependencies.ts b/x-pack/test/apm_api_integration/tests/dependencies/top_dependencies.spec.ts similarity index 98% rename from x-pack/test/apm_api_integration/tests/dependencies/top_dependencies.ts rename to x-pack/test/apm_api_integration/tests/dependencies/top_dependencies.spec.ts index 6d32defed460d..d2ead8048358b 100644 --- a/x-pack/test/apm_api_integration/tests/dependencies/top_dependencies.ts +++ b/x-pack/test/apm_api_integration/tests/dependencies/top_dependencies.spec.ts @@ -7,7 +7,6 @@ import expect from '@kbn/expect'; import { APIReturnType } from '../../../../plugins/apm/public/services/rest/createCallApmApi'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; import { dataConfig, generateData } from './generate_data'; import { NodeType, BackendNode } from '../../../../plugins/apm/common/connections'; import { roundNumber } from '../../utils'; @@ -15,6 +14,7 @@ import { roundNumber } from '../../utils'; type TopDependencies = APIReturnType<'GET /internal/apm/backends/top_backends'>; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const synthtraceEsClient = getService('synthtraceEsClient'); diff --git a/x-pack/test/apm_api_integration/tests/error_rate/service_apis.ts b/x-pack/test/apm_api_integration/tests/error_rate/service_apis.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/error_rate/service_apis.ts rename to x-pack/test/apm_api_integration/tests/error_rate/service_apis.spec.ts index d5bf0bd21c7e8..7aca21f4fc7f6 100644 --- a/x-pack/test/apm_api_integration/tests/error_rate/service_apis.ts +++ b/x-pack/test/apm_api_integration/tests/error_rate/service_apis.spec.ts @@ -11,9 +11,9 @@ import { LatencyAggregationType } from '../../../../plugins/apm/common/latency_a import { isFiniteNumber } from '../../../../plugins/apm/common/utils/is_finite_number'; import { PromiseReturnType } from '../../../../plugins/observability/typings/common'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const synthtraceEsClient = getService('synthtraceEsClient'); diff --git a/x-pack/test/apm_api_integration/tests/errors/distribution.ts b/x-pack/test/apm_api_integration/tests/errors/distribution.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/errors/distribution.ts rename to x-pack/test/apm_api_integration/tests/errors/distribution.spec.ts index 487b5ff8a12c9..ed2cc468001f6 100644 --- a/x-pack/test/apm_api_integration/tests/errors/distribution.ts +++ b/x-pack/test/apm_api_integration/tests/errors/distribution.spec.ts @@ -13,13 +13,13 @@ import { } from '../../../../plugins/apm/public/services/rest/createCallApmApi'; import { RecursivePartial } from '../../../../plugins/apm/typings/common'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; import { config, generateData } from './generate_data'; type ErrorsDistribution = APIReturnType<'GET /internal/apm/services/{serviceName}/errors/distribution'>; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const synthtraceEsClient = getService('synthtraceEsClient'); diff --git a/x-pack/test/apm_api_integration/tests/errors/error_group_list.ts b/x-pack/test/apm_api_integration/tests/errors/error_group_list.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/errors/error_group_list.ts rename to x-pack/test/apm_api_integration/tests/errors/error_group_list.spec.ts index 4b5cbf4a2662a..5fc3f70d0d023 100644 --- a/x-pack/test/apm_api_integration/tests/errors/error_group_list.ts +++ b/x-pack/test/apm_api_integration/tests/errors/error_group_list.spec.ts @@ -12,11 +12,11 @@ import { } from '../../../../plugins/apm/public/services/rest/createCallApmApi'; import { RecursivePartial } from '../../../../plugins/apm/typings/common'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; type ErrorGroups = APIReturnType<'GET /internal/apm/services/{serviceName}/errors'>['errorGroups']; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const synthtraceEsClient = getService('synthtraceEsClient'); diff --git a/x-pack/test/apm_api_integration/tests/errors/group_id.ts b/x-pack/test/apm_api_integration/tests/errors/group_id.spec.ts similarity index 98% rename from x-pack/test/apm_api_integration/tests/errors/group_id.ts rename to x-pack/test/apm_api_integration/tests/errors/group_id.spec.ts index ef9e293355a7f..9fc5165ed575e 100644 --- a/x-pack/test/apm_api_integration/tests/errors/group_id.ts +++ b/x-pack/test/apm_api_integration/tests/errors/group_id.spec.ts @@ -11,13 +11,13 @@ import { } from '../../../../plugins/apm/public/services/rest/createCallApmApi'; import { RecursivePartial } from '../../../../plugins/apm/typings/common'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; import { config, generateData } from './generate_data'; type ErrorsDistribution = APIReturnType<'GET /internal/apm/services/{serviceName}/errors/{groupId}'>; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const synthtraceEsClient = getService('synthtraceEsClient'); diff --git a/x-pack/test/apm_api_integration/tests/event_metadata/event_metadata.ts b/x-pack/test/apm_api_integration/tests/event_metadata/event_metadata.spec.ts similarity index 98% rename from x-pack/test/apm_api_integration/tests/event_metadata/event_metadata.ts rename to x-pack/test/apm_api_integration/tests/event_metadata/event_metadata.spec.ts index fe461a94783a5..d1cc42a4c7c9d 100644 --- a/x-pack/test/apm_api_integration/tests/event_metadata/event_metadata.ts +++ b/x-pack/test/apm_api_integration/tests/event_metadata/event_metadata.spec.ts @@ -8,9 +8,9 @@ import expect from '@kbn/expect'; import { PROCESSOR_EVENT } from '../../../../plugins/apm/common/elasticsearch_fieldnames'; import { ProcessorEvent } from '../../../../plugins/apm/common/processor_event'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const esClient = getService('es'); diff --git a/x-pack/test/apm_api_integration/tests/feature_controls.ts b/x-pack/test/apm_api_integration/tests/feature_controls.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/feature_controls.ts rename to x-pack/test/apm_api_integration/tests/feature_controls.spec.ts index ef3ba5d61fb54..f20aaaff2b23d 100644 --- a/x-pack/test/apm_api_integration/tests/feature_controls.ts +++ b/x-pack/test/apm_api_integration/tests/feature_controls.spec.ts @@ -7,9 +7,9 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../common/ftr_provider_context'; -import { registry } from '../common/registry'; export default function featureControlsTests({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmWriteUser'); const supertestWithoutAuth = getService('supertestWithoutAuth'); const security = getService('security'); diff --git a/x-pack/test/apm_api_integration/tests/historical_data/has_data.ts b/x-pack/test/apm_api_integration/tests/historical_data/has_data.spec.ts similarity index 96% rename from x-pack/test/apm_api_integration/tests/historical_data/has_data.ts rename to x-pack/test/apm_api_integration/tests/historical_data/has_data.spec.ts index 70048c3d39210..e138742b25d4c 100644 --- a/x-pack/test/apm_api_integration/tests/historical_data/has_data.ts +++ b/x-pack/test/apm_api_integration/tests/historical_data/has_data.spec.ts @@ -7,9 +7,9 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('supertest'); const archiveName = 'apm_8.0.0'; diff --git a/x-pack/test/apm_api_integration/tests/index.ts b/x-pack/test/apm_api_integration/tests/index.ts index 46966834a176e..59764cf021c4a 100644 --- a/x-pack/test/apm_api_integration/tests/index.ts +++ b/x-pack/test/apm_api_integration/tests/index.ts @@ -4,265 +4,25 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import glob from 'glob'; +import path from 'path'; import { FtrProviderContext } from '../common/ftr_provider_context'; -import { registry } from '../common/registry'; -export default function apmApiIntegrationTests(providerContext: FtrProviderContext) { - const { loadTestFile } = providerContext; +const cwd = path.join(__dirname); + +export default function apmApiIntegrationTests({ getService, loadTestFile }: FtrProviderContext) { + const registry = getService('registry'); describe('APM API tests', function () { this.tags('ciGroup1'); - // inspect feature - describe('inspect/inspect', function () { - loadTestFile(require.resolve('./inspect/inspect')); - }); - - // alerts - describe('alerts/chart_preview', function () { - loadTestFile(require.resolve('./alerts/chart_preview')); - }); - - describe('alerts/rule_registry', function () { - loadTestFile(require.resolve('./alerts/rule_registry')); - }); - - // correlations - describe('correlations/failed_transactions', function () { - loadTestFile(require.resolve('./correlations/failed_transactions')); - }); - - describe('correlations/latency', function () { - loadTestFile(require.resolve('./correlations/latency')); - }); - - describe('event_metadata/event_metadata', function () { - loadTestFile(require.resolve('./event_metadata/event_metadata')); - }); - - describe('metrics_charts/metrics_charts', function () { - loadTestFile(require.resolve('./metrics_charts/metrics_charts')); - }); - - describe('observability_overview/has_data', function () { - loadTestFile(require.resolve('./observability_overview/has_data')); - }); - - describe('observability_overview/observability_overview', function () { - loadTestFile(require.resolve('./observability_overview/observability_overview')); - }); - - describe('service_maps/service_maps', function () { - loadTestFile(require.resolve('./service_maps/service_maps')); - }); - - // Service overview - describe('service_overview/dependencies', function () { - loadTestFile(require.resolve('./service_overview/dependencies')); - }); - - describe('service_overview/instances_main_statistics', function () { - loadTestFile(require.resolve('./service_overview/instances_main_statistics')); - }); - - describe('service_overview/instances_detailed_statistics', function () { - loadTestFile(require.resolve('./service_overview/instances_detailed_statistics')); - }); - - describe('service_overview/instance_details', function () { - loadTestFile(require.resolve('./service_overview/instance_details')); - }); - - // Services - describe('services/agent', function () { - loadTestFile(require.resolve('./services/agent')); - }); - - describe('services/annotations', function () { - loadTestFile(require.resolve('./services/annotations')); - loadTestFile(require.resolve('./services/derived_annotations')); - }); - - describe('services/service_details', function () { - loadTestFile(require.resolve('./services/service_details')); - }); - - describe('services/service_icons', function () { - loadTestFile(require.resolve('./services/service_icons')); - }); - - describe('services/throughput', function () { - loadTestFile(require.resolve('./services/throughput')); - }); - - describe('service apis throughput', function () { - loadTestFile(require.resolve('./throughput/service_apis')); - }); - - describe('dependencies throughput', function () { - loadTestFile(require.resolve('./throughput/dependencies_apis')); - }); - - describe('services/top_services', function () { - loadTestFile(require.resolve('./services/top_services')); - }); - - describe('services/transaction_types', function () { - loadTestFile(require.resolve('./services/transaction_types')); - }); - - describe('services/error_groups_main_statistics', function () { - loadTestFile(require.resolve('./services/error_groups/error_groups_main_statistics')); - }); - - describe('services/error_groups_detailed_statistics', function () { - loadTestFile(require.resolve('./services/error_groups/error_groups_detailed_statistics')); - }); - - describe('services/detailed_statistics', function () { - loadTestFile(require.resolve('./services/services_detailed_statistics')); - }); - - // Settinges - describe('settings/anomaly_detection/basic', function () { - loadTestFile(require.resolve('./settings/anomaly_detection/basic')); - }); - - describe('settings/anomaly_detection/no_access_user', function () { - loadTestFile(require.resolve('./settings/anomaly_detection/no_access_user')); - }); - - describe('settings/anomaly_detection/read_user', function () { - loadTestFile(require.resolve('./settings/anomaly_detection/read_user')); - }); - - describe('settings/anomaly_detection/write_user', function () { - loadTestFile(require.resolve('./settings/anomaly_detection/write_user')); - }); - - describe('settings/agent_configuration', function () { - loadTestFile(require.resolve('./settings/agent_configuration')); - }); - - describe('settings/custom_link', function () { - loadTestFile(require.resolve('./settings/custom_link')); - }); - - // suggestions - describe('suggestions', function () { - loadTestFile(require.resolve('./suggestions/suggestions')); - }); - - // traces - describe('traces/top_traces', function () { - loadTestFile(require.resolve('./traces/top_traces')); - }); - describe('/internal/apm/traces/{traceId}', function () { - loadTestFile(require.resolve('./traces/trace_by_id')); - }); - - // transactions - describe('transactions/breakdown', function () { - loadTestFile(require.resolve('./transactions/breakdown')); - }); - - describe('transactions/trace_samples', function () { - loadTestFile(require.resolve('./transactions/trace_samples')); - }); - - describe('transactions/error_rate', function () { - loadTestFile(require.resolve('./transactions/error_rate')); - }); - - describe('transactions/latency_overall_distribution', function () { - loadTestFile(require.resolve('./transactions/latency_overall_distribution')); - }); - - describe('transactions/latency', function () { - loadTestFile(require.resolve('./transactions/latency')); - }); - - describe('transactions/transactions_groups_main_statistics', function () { - loadTestFile(require.resolve('./transactions/transactions_groups_main_statistics')); - }); - - describe('transactions/transactions_groups_detailed_statistics', function () { - loadTestFile(require.resolve('./transactions/transactions_groups_detailed_statistics')); - }); - - // feature control - describe('feature_controls', function () { - loadTestFile(require.resolve('./feature_controls')); - }); - - // CSM - describe('csm/csm_services', function () { - loadTestFile(require.resolve('./csm/csm_services')); - }); - - describe('csm/has_rum_data', function () { - loadTestFile(require.resolve('./csm/has_rum_data')); - }); - - describe('csm/js_errors', function () { - loadTestFile(require.resolve('./csm/js_errors')); - }); - - describe('csm/long_task_metrics', function () { - loadTestFile(require.resolve('./csm/long_task_metrics')); - }); - - describe('csm/page_load_dist', function () { - loadTestFile(require.resolve('./csm/page_load_dist')); - }); - - describe('csm/page_views', function () { - loadTestFile(require.resolve('./csm/page_views')); - }); - - describe('csm/url_search', function () { - loadTestFile(require.resolve('./csm/url_search')); - }); - - describe('csm/web_core_vitals', function () { - loadTestFile(require.resolve('./csm/web_core_vitals')); - }); - - describe('historical_data/has_data', function () { - loadTestFile(require.resolve('./historical_data/has_data')); - }); - - describe('error_rate/service_apis', function () { - loadTestFile(require.resolve('./error_rate/service_apis')); - }); - - describe('latency/service_apis', function () { - loadTestFile(require.resolve('./latency/service_apis')); - }); - - // Errors - describe('errors/group_id', function () { - loadTestFile(require.resolve('./errors/group_id')); - }); - - describe('errors/distribution', function () { - loadTestFile(require.resolve('./errors/distribution')); - }); - - describe('errors/error_group_list', function () { - loadTestFile(require.resolve('./errors/error_group_list')); - }); - - // Dependencies - describe('dependencies/metadata', function () { - loadTestFile(require.resolve('./dependencies/metadata')); - }); - - describe('dependencies/top_dependencies', function () { - loadTestFile(require.resolve('./dependencies/top_dependencies')); + const tests = glob.sync('**/*.spec.ts', { cwd }); + tests.forEach((test) => { + describe(test, function () { + loadTestFile(require.resolve(`./${test}`)); + }); }); - registry.run(providerContext); + registry.run(); }); } diff --git a/x-pack/test/apm_api_integration/tests/inspect/inspect.ts b/x-pack/test/apm_api_integration/tests/inspect/inspect.spec.ts similarity index 96% rename from x-pack/test/apm_api_integration/tests/inspect/inspect.ts rename to x-pack/test/apm_api_integration/tests/inspect/inspect.spec.ts index a010c150124f0..443a03692aca9 100644 --- a/x-pack/test/apm_api_integration/tests/inspect/inspect.ts +++ b/x-pack/test/apm_api_integration/tests/inspect/inspect.spec.ts @@ -7,11 +7,11 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; import archives_metadata from '../../common/fixtures/es_archiver/archives_metadata'; export default function customLinksTests({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const archiveName = 'apm_8.0.0'; @@ -49,7 +49,7 @@ export default function customLinksTests({ getService }: FtrProviderContext) { }, }); expect(status).to.be(200); - expect(body._inspect?.length).to.be(1); + expect(body._inspect).not.to.be.empty(); // @ts-expect-error expect(Object.keys(body._inspect[0])).to.eql([ diff --git a/x-pack/test/apm_api_integration/tests/latency/service_apis.ts b/x-pack/test/apm_api_integration/tests/latency/service_apis.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/latency/service_apis.ts rename to x-pack/test/apm_api_integration/tests/latency/service_apis.spec.ts index aa8282ccb0cc5..e87f03efeeefe 100644 --- a/x-pack/test/apm_api_integration/tests/latency/service_apis.ts +++ b/x-pack/test/apm_api_integration/tests/latency/service_apis.spec.ts @@ -11,9 +11,9 @@ import { LatencyAggregationType } from '../../../../plugins/apm/common/latency_a import { isFiniteNumber } from '../../../../plugins/apm/common/utils/is_finite_number'; import { PromiseReturnType } from '../../../../plugins/observability/typings/common'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const synthtraceEsClient = getService('synthtraceEsClient'); diff --git a/x-pack/test/apm_api_integration/tests/metrics_charts/metrics_charts.ts b/x-pack/test/apm_api_integration/tests/metrics_charts/metrics_charts.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/metrics_charts/metrics_charts.ts rename to x-pack/test/apm_api_integration/tests/metrics_charts/metrics_charts.spec.ts index 7b621de111ef8..74af2c2dba008 100644 --- a/x-pack/test/apm_api_integration/tests/metrics_charts/metrics_charts.ts +++ b/x-pack/test/apm_api_integration/tests/metrics_charts/metrics_charts.spec.ts @@ -10,7 +10,6 @@ import { first } from 'lodash'; import { MetricsChartsByAgentAPIResponse } from '../../../../plugins/apm/server/lib/metrics/get_metrics_chart_data_by_agent'; import { GenericMetricsChart } from '../../../../plugins/apm/server/lib/metrics/transform_metrics_chart'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; interface ChartResponse { body: MetricsChartsByAgentAPIResponse; @@ -18,6 +17,7 @@ interface ChartResponse { } export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); registry.when( diff --git a/x-pack/test/apm_api_integration/tests/observability_overview/has_data.ts b/x-pack/test/apm_api_integration/tests/observability_overview/has_data.spec.ts similarity index 97% rename from x-pack/test/apm_api_integration/tests/observability_overview/has_data.ts rename to x-pack/test/apm_api_integration/tests/observability_overview/has_data.spec.ts index 90a01c472e13e..3aab948cd4f69 100644 --- a/x-pack/test/apm_api_integration/tests/observability_overview/has_data.ts +++ b/x-pack/test/apm_api_integration/tests/observability_overview/has_data.spec.ts @@ -8,9 +8,9 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); registry.when( diff --git a/x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.ts b/x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.ts rename to x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.spec.ts index 9082c5dec3b79..6b6d61fdb1d35 100644 --- a/x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.ts +++ b/x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.spec.ts @@ -8,11 +8,11 @@ import { service, timerange } from '@elastic/apm-synthtrace'; import expect from '@kbn/expect'; import { meanBy, sumBy } from 'lodash'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; import { PromiseReturnType } from '../../../../plugins/observability/typings/common'; import { roundNumber } from '../../utils'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const synthtraceEsClient = getService('synthtraceEsClient'); diff --git a/x-pack/test/apm_api_integration/tests/service_maps/service_maps.ts b/x-pack/test/apm_api_integration/tests/service_maps/service_maps.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/service_maps/service_maps.ts rename to x-pack/test/apm_api_integration/tests/service_maps/service_maps.spec.ts index d4733785c62b8..bf607030c07d3 100644 --- a/x-pack/test/apm_api_integration/tests/service_maps/service_maps.ts +++ b/x-pack/test/apm_api_integration/tests/service_maps/service_maps.spec.ts @@ -12,9 +12,9 @@ import { isEmpty, orderBy, uniq } from 'lodash'; import archives_metadata from '../../common/fixtures/es_archiver/archives_metadata'; import { PromiseReturnType } from '../../../../plugins/observability/typings/common'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function serviceMapsApiTests({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); const supertestAsApmReadUserWithoutMlAccess = getService( 'legacySupertestAsApmReadUserWithoutMlAccess' diff --git a/x-pack/test/apm_api_integration/tests/service_overview/__snapshots__/instance_details.snap b/x-pack/test/apm_api_integration/tests/service_overview/__snapshots__/instance_details.spec.snap similarity index 97% rename from x-pack/test/apm_api_integration/tests/service_overview/__snapshots__/instance_details.snap rename to x-pack/test/apm_api_integration/tests/service_overview/__snapshots__/instance_details.spec.snap index 8eb8ad2adb164..357b6111da67d 100644 --- a/x-pack/test/apm_api_integration/tests/service_overview/__snapshots__/instance_details.snap +++ b/x-pack/test/apm_api_integration/tests/service_overview/__snapshots__/instance_details.spec.snap @@ -2,7 +2,6 @@ exports[`APM API tests basic apm_8.0.0 Instance details when data is loaded fetch instance details return the correct data 1`] = ` Object { - "@timestamp": "2021-08-03T06:57:50.204Z", "agent": Object { "ephemeral_id": "2745d454-f57f-4473-a09b-fe6bef295860", "name": "java", diff --git a/x-pack/test/apm_api_integration/tests/service_overview/__snapshots__/instances_detailed_statistics.snap b/x-pack/test/apm_api_integration/tests/service_overview/__snapshots__/instances_detailed_statistics.spec.snap similarity index 100% rename from x-pack/test/apm_api_integration/tests/service_overview/__snapshots__/instances_detailed_statistics.snap rename to x-pack/test/apm_api_integration/tests/service_overview/__snapshots__/instances_detailed_statistics.spec.snap diff --git a/x-pack/test/apm_api_integration/tests/service_overview/dependencies/index.ts b/x-pack/test/apm_api_integration/tests/service_overview/dependencies/index.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/service_overview/dependencies/index.ts rename to x-pack/test/apm_api_integration/tests/service_overview/dependencies/index.spec.ts index 1549e403c1377..507b3d21e1b3f 100644 --- a/x-pack/test/apm_api_integration/tests/service_overview/dependencies/index.ts +++ b/x-pack/test/apm_api_integration/tests/service_overview/dependencies/index.spec.ts @@ -17,10 +17,10 @@ import { import { APIReturnType } from '../../../../../plugins/apm/public/services/rest/createCallApmApi'; import archives from '../../../common/fixtures/es_archiver/archives_metadata'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; -import { registry } from '../../../common/registry'; import { apmDependenciesMapping, createServiceDependencyDocs } from './es_utils'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const es = getService('es'); diff --git a/x-pack/test/apm_api_integration/tests/service_overview/instance_details.ts b/x-pack/test/apm_api_integration/tests/service_overview/instance_details.spec.ts similarity index 95% rename from x-pack/test/apm_api_integration/tests/service_overview/instance_details.ts rename to x-pack/test/apm_api_integration/tests/service_overview/instance_details.spec.ts index f3de8823199a8..04e32705efad9 100644 --- a/x-pack/test/apm_api_integration/tests/service_overview/instance_details.ts +++ b/x-pack/test/apm_api_integration/tests/service_overview/instance_details.spec.ts @@ -6,9 +6,9 @@ */ import url from 'url'; import expect from '@kbn/expect'; +import { omit } from 'lodash'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import archives from '../../common/fixtures/es_archiver/archives_metadata'; -import { registry } from '../../common/registry'; import { APIReturnType } from '../../../../plugins/apm/public/services/rest/createCallApmApi'; import { getServiceNodeIds } from './get_service_node_ids'; import { createApmApiClient } from '../../common/apm_api_supertest'; @@ -17,6 +17,7 @@ type ServiceOverviewInstanceDetails = APIReturnType<'GET /internal/apm/services/{serviceName}/service_overview_instances/details/{serviceNodeName}'>; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); const apmApiSupertest = createApmApiClient(supertest); @@ -77,7 +78,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('return the correct data', () => { - expectSnapshot(response.body).toMatch(); + expectSnapshot(omit(response.body, '@timestamp')).toMatch(); }); }); } diff --git a/x-pack/test/apm_api_integration/tests/service_overview/instances_detailed_statistics.ts b/x-pack/test/apm_api_integration/tests/service_overview/instances_detailed_statistics.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/service_overview/instances_detailed_statistics.ts rename to x-pack/test/apm_api_integration/tests/service_overview/instances_detailed_statistics.spec.ts index 9d9fb6a221cf6..719b0b487172c 100644 --- a/x-pack/test/apm_api_integration/tests/service_overview/instances_detailed_statistics.ts +++ b/x-pack/test/apm_api_integration/tests/service_overview/instances_detailed_statistics.spec.ts @@ -13,11 +13,11 @@ import { isFiniteNumber } from '../../../../plugins/apm/common/utils/is_finite_n import { APIReturnType } from '../../../../plugins/apm/public/services/rest/createCallApmApi'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import archives from '../../common/fixtures/es_archiver/archives_metadata'; -import { registry } from '../../common/registry'; import { createApmApiClient } from '../../common/apm_api_supertest'; import { getServiceNodeIds } from './get_service_node_ids'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); const apmApiSupertest = createApmApiClient(supertest); diff --git a/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.ts b/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.ts rename to x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.spec.ts index 909e58a5566a5..5800ddf00480a 100644 --- a/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.ts +++ b/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.spec.ts @@ -13,13 +13,13 @@ import { APIReturnType } from '../../../../plugins/apm/public/services/rest/crea import { isFiniteNumber } from '../../../../plugins/apm/common/utils/is_finite_number'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import archives from '../../common/fixtures/es_archiver/archives_metadata'; -import { registry } from '../../common/registry'; import { LatencyAggregationType } from '../../../../plugins/apm/common/latency_aggregation_types'; import { ENVIRONMENT_ALL } from '../../../../plugins/apm/common/environment_filter_values'; import { SERVICE_NODE_NAME_MISSING } from '../../../../plugins/apm/common/service_nodes'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const synthtraceEsClient = getService('synthtraceEsClient'); diff --git a/x-pack/test/apm_api_integration/tests/services/__snapshots__/error_groups_detailed_statistics.snap b/x-pack/test/apm_api_integration/tests/services/__snapshots__/error_groups_detailed_statistics.spec.snap similarity index 100% rename from x-pack/test/apm_api_integration/tests/services/__snapshots__/error_groups_detailed_statistics.snap rename to x-pack/test/apm_api_integration/tests/services/__snapshots__/error_groups_detailed_statistics.spec.snap diff --git a/x-pack/test/apm_api_integration/tests/services/agent.ts b/x-pack/test/apm_api_integration/tests/services/agent.spec.ts similarity index 96% rename from x-pack/test/apm_api_integration/tests/services/agent.ts rename to x-pack/test/apm_api_integration/tests/services/agent.spec.ts index fcd21f5a1a072..c1c1cc641c5fc 100644 --- a/x-pack/test/apm_api_integration/tests/services/agent.ts +++ b/x-pack/test/apm_api_integration/tests/services/agent.spec.ts @@ -8,9 +8,9 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import archives from '../../common/fixtures/es_archiver/archives_metadata'; -import { registry } from '../../common/registry'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); const archiveName = 'apm_8.0.0'; diff --git a/x-pack/test/apm_api_integration/tests/services/annotations.ts b/x-pack/test/apm_api_integration/tests/services/annotations.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/services/annotations.ts rename to x-pack/test/apm_api_integration/tests/services/annotations.spec.ts index 25737ce8cce9a..2acfeac87880f 100644 --- a/x-pack/test/apm_api_integration/tests/services/annotations.ts +++ b/x-pack/test/apm_api_integration/tests/services/annotations.spec.ts @@ -9,11 +9,11 @@ import expect from '@kbn/expect'; import { merge, cloneDeep, isPlainObject } from 'lodash'; import { JsonObject } from '@kbn/utility-types'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; const DEFAULT_INDEX_NAME = 'observability-annotations'; export default function annotationApiTests({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertestRead = getService('legacySupertestAsApmReadUser'); const supertestWrite = getService('legacySupertestAsApmAnnotationsWriteUser'); const es = getService('es'); diff --git a/x-pack/test/apm_api_integration/tests/services/derived_annotations.ts b/x-pack/test/apm_api_integration/tests/services/derived_annotations.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/services/derived_annotations.ts rename to x-pack/test/apm_api_integration/tests/services/derived_annotations.spec.ts index c9ee61557deb6..6a27f68be5d4f 100644 --- a/x-pack/test/apm_api_integration/tests/services/derived_annotations.ts +++ b/x-pack/test/apm_api_integration/tests/services/derived_annotations.spec.ts @@ -9,9 +9,9 @@ import expect from '@kbn/expect'; import { APIReturnType } from '../../../../plugins/apm/public/services/rest/createCallApmApi'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function annotationApiTests({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const es = getService('es'); diff --git a/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.ts b/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.ts rename to x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.spec.ts index 54bbd4eb0bf71..e94de1d5410f1 100644 --- a/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.ts +++ b/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.spec.ts @@ -15,7 +15,6 @@ import { } from '../../../../../plugins/apm/public/services/rest/createCallApmApi'; import { RecursivePartial } from '../../../../../plugins/apm/typings/common'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; -import { registry } from '../../../common/registry'; import { config, generateData } from './generate_data'; import { getErrorGroupIds } from './get_error_group_ids'; @@ -23,6 +22,7 @@ type ErrorGroupsDetailedStatistics = APIReturnType<'GET /internal/apm/services/{serviceName}/error_groups/detailed_statistics'>; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const synthtraceEsClient = getService('synthtraceEsClient'); diff --git a/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_main_statistics.ts b/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_main_statistics.spec.ts similarity index 98% rename from x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_main_statistics.ts rename to x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_main_statistics.spec.ts index bc6bd023a0f5e..3d8ddfe38cf5e 100644 --- a/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_main_statistics.ts +++ b/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_main_statistics.spec.ts @@ -12,13 +12,13 @@ import { } from '../../../../../plugins/apm/public/services/rest/createCallApmApi'; import { RecursivePartial } from '../../../../../plugins/apm/typings/common'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; -import { registry } from '../../../common/registry'; import { generateData, config } from './generate_data'; type ErrorGroupsMainStatistics = APIReturnType<'GET /internal/apm/services/{serviceName}/error_groups/main_statistics'>; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const synthtraceEsClient = getService('synthtraceEsClient'); diff --git a/x-pack/test/apm_api_integration/tests/services/service_details.ts b/x-pack/test/apm_api_integration/tests/services/service_details.spec.ts similarity index 98% rename from x-pack/test/apm_api_integration/tests/services/service_details.ts rename to x-pack/test/apm_api_integration/tests/services/service_details.spec.ts index 28a3ee3ef82fd..0031569308224 100644 --- a/x-pack/test/apm_api_integration/tests/services/service_details.ts +++ b/x-pack/test/apm_api_integration/tests/services/service_details.spec.ts @@ -9,9 +9,9 @@ import expect from '@kbn/expect'; import url from 'url'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import archives from '../../common/fixtures/es_archiver/archives_metadata'; -import { registry } from '../../common/registry'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); const archiveName = 'apm_8.0.0'; diff --git a/x-pack/test/apm_api_integration/tests/services/service_icons.ts b/x-pack/test/apm_api_integration/tests/services/service_icons.spec.ts similarity index 97% rename from x-pack/test/apm_api_integration/tests/services/service_icons.ts rename to x-pack/test/apm_api_integration/tests/services/service_icons.spec.ts index e948c6981d6c6..f8b66a621e83e 100644 --- a/x-pack/test/apm_api_integration/tests/services/service_icons.ts +++ b/x-pack/test/apm_api_integration/tests/services/service_icons.spec.ts @@ -9,9 +9,9 @@ import expect from '@kbn/expect'; import url from 'url'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import archives from '../../common/fixtures/es_archiver/archives_metadata'; -import { registry } from '../../common/registry'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); const archiveName = 'apm_8.0.0'; diff --git a/x-pack/test/apm_api_integration/tests/services/services_detailed_statistics.ts b/x-pack/test/apm_api_integration/tests/services/services_detailed_statistics.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/services/services_detailed_statistics.ts rename to x-pack/test/apm_api_integration/tests/services/services_detailed_statistics.spec.ts index d605c5f313825..742221d2a66e1 100644 --- a/x-pack/test/apm_api_integration/tests/services/services_detailed_statistics.ts +++ b/x-pack/test/apm_api_integration/tests/services/services_detailed_statistics.spec.ts @@ -7,7 +7,6 @@ import expect from '@kbn/expect'; import url from 'url'; import moment from 'moment'; -import { registry } from '../../common/registry'; import archives_metadata from '../../common/fixtures/es_archiver/archives_metadata'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import { APIReturnType } from '../../../../plugins/apm/public/services/rest/createCallApmApi'; @@ -17,6 +16,7 @@ type ServicesDetailedStatisticsReturn = APIReturnType<'GET /internal/apm/services/detailed_statistics'>; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); const archiveName = 'apm_8.0.0'; diff --git a/x-pack/test/apm_api_integration/tests/services/throughput.ts b/x-pack/test/apm_api_integration/tests/services/throughput.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/services/throughput.ts rename to x-pack/test/apm_api_integration/tests/services/throughput.spec.ts index a9865a0c3bb38..077119156c641 100644 --- a/x-pack/test/apm_api_integration/tests/services/throughput.ts +++ b/x-pack/test/apm_api_integration/tests/services/throughput.spec.ts @@ -16,12 +16,12 @@ import { } from '../../../../plugins/apm/public/services/rest/createCallApmApi'; import { RecursivePartial } from '../../../../plugins/apm/typings/common'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; import { roundNumber } from '../../utils'; type ThroughputReturn = APIReturnType<'GET /internal/apm/services/{serviceName}/throughput'>; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const synthtraceEsClient = getService('synthtraceEsClient'); @@ -64,7 +64,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); registry.when( - 'data is loaded', + 'Throughput when data is loaded', { config: 'basic', archives: ['apm_mappings_only_8.0.0'] }, () => { describe('Throughput chart api', () => { diff --git a/x-pack/test/apm_api_integration/tests/services/top_services.ts b/x-pack/test/apm_api_integration/tests/services/top_services.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/services/top_services.ts rename to x-pack/test/apm_api_integration/tests/services/top_services.spec.ts index 42d98f38e4e4a..375206d0a0bc0 100644 --- a/x-pack/test/apm_api_integration/tests/services/top_services.ts +++ b/x-pack/test/apm_api_integration/tests/services/top_services.spec.ts @@ -12,10 +12,10 @@ import { APIReturnType } from '../../../../plugins/apm/public/services/rest/crea import { PromiseReturnType } from '../../../../plugins/observability/typings/common'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import archives_metadata from '../../common/fixtures/es_archiver/archives_metadata'; -import { registry } from '../../common/registry'; import { ENVIRONMENT_ALL } from '../../../../plugins/apm/common/environment_filter_values'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); const apmApiClient = getService('apmApiClient'); diff --git a/x-pack/test/apm_api_integration/tests/services/transaction_types.ts b/x-pack/test/apm_api_integration/tests/services/transaction_types.spec.ts similarity index 97% rename from x-pack/test/apm_api_integration/tests/services/transaction_types.ts rename to x-pack/test/apm_api_integration/tests/services/transaction_types.spec.ts index 4b752971e82f8..82afa69029147 100644 --- a/x-pack/test/apm_api_integration/tests/services/transaction_types.ts +++ b/x-pack/test/apm_api_integration/tests/services/transaction_types.spec.ts @@ -8,9 +8,9 @@ import expect from '@kbn/expect'; import archives_metadata from '../../common/fixtures/es_archiver/archives_metadata'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); const archiveName = 'apm_8.0.0'; diff --git a/x-pack/test/apm_api_integration/tests/settings/agent_configuration.ts b/x-pack/test/apm_api_integration/tests/settings/agent_configuration.spec.ts similarity index 93% rename from x-pack/test/apm_api_integration/tests/settings/agent_configuration.ts rename to x-pack/test/apm_api_integration/tests/settings/agent_configuration.spec.ts index 377c933144880..df504ec7444d7 100644 --- a/x-pack/test/apm_api_integration/tests/settings/agent_configuration.ts +++ b/x-pack/test/apm_api_integration/tests/settings/agent_configuration.spec.ts @@ -5,15 +5,17 @@ * 2.0. */ +import { inspect } from 'util'; + import expect from '@kbn/expect'; import { omit, orderBy } from 'lodash'; import { AgentConfigurationIntake } from '../../../../plugins/apm/common/agent_configuration/configuration_types'; import { AgentConfigSearchParams } from '../../../../plugins/apm/server/routes/settings/agent_configuration'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function agentConfigurationTests({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const log = getService('log'); @@ -133,19 +135,19 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte it('can create and delete config', async () => { // assert that config does not exist - await expectStatusCode(() => searchConfigurations(searchParams), 404); + await expectMissing(() => searchConfigurations(searchParams)); // create config await createConfiguration(newConfig); // assert that config now exists - await expectStatusCode(() => searchConfigurations(searchParams), 200); + await expectExists(() => searchConfigurations(searchParams)); // delete config await deleteConfiguration(newConfig); // assert that config was deleted - await expectStatusCode(() => searchConfigurations(searchParams), 404); + await expectMissing(() => searchConfigurations(searchParams)); }); describe('when a configuration exists', () => { @@ -439,6 +441,16 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte }); } ); + + async function expectExists(fn: () => ReturnType) { + const response = await fn(); + expect(response.body).not.to.be.empty(); + } + + async function expectMissing(fn: () => ReturnType) { + const response = await fn(); + expect(response.body).to.be.empty(); + } } async function waitFor(cb: () => Promise, retries = 50): Promise { @@ -464,10 +476,23 @@ async function expectStatusCode( }>, statusCode: number ) { + let res; try { - const res = await fn(); - expect(res.status).to.be(statusCode); + res = await fn(); } catch (e) { - expect(e.res.status).to.be(statusCode); + if (e && e.res && e.res.status) { + if (e.res.status === statusCode) { + return; + } + throw new Error( + `Expected a [${statusCode}] response, got [${e.res.status}]: ${inspect(e.res)}` + ); + } else { + throw new Error( + `Unexpected rejection value, expected error with .res response property: ${inspect(e)}` + ); + } } + + expect(res.status).to.be(statusCode); } diff --git a/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/basic.ts b/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/basic.spec.ts similarity index 97% rename from x-pack/test/apm_api_integration/tests/settings/anomaly_detection/basic.ts rename to x-pack/test/apm_api_integration/tests/settings/anomaly_detection/basic.spec.ts index 7e05bd3faabfa..f7c35e92e08a0 100644 --- a/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/basic.ts +++ b/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/basic.spec.ts @@ -6,10 +6,10 @@ */ import expect from '@kbn/expect'; -import { registry } from '../../../common/registry'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; export default function apiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const noAccessUser = getService('legacySupertestAsNoAccessUser'); const readUser = getService('legacySupertestAsApmReadUser'); const writeUser = getService('legacySupertestAsApmWriteUser'); diff --git a/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/no_access_user.ts b/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/no_access_user.spec.ts similarity index 96% rename from x-pack/test/apm_api_integration/tests/settings/anomaly_detection/no_access_user.ts rename to x-pack/test/apm_api_integration/tests/settings/anomaly_detection/no_access_user.spec.ts index 0b73b67c8e4c2..eefd5226ee7d0 100644 --- a/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/no_access_user.ts +++ b/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/no_access_user.spec.ts @@ -6,10 +6,10 @@ */ import expect from '@kbn/expect'; -import { registry } from '../../../common/registry'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; export default function apiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const noAccessUser = getService('legacySupertestAsNoAccessUser'); function getJobs() { diff --git a/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/read_user.ts b/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/read_user.spec.ts similarity index 96% rename from x-pack/test/apm_api_integration/tests/settings/anomaly_detection/read_user.ts rename to x-pack/test/apm_api_integration/tests/settings/anomaly_detection/read_user.spec.ts index 982a47001f826..75967dc9a8ff9 100644 --- a/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/read_user.ts +++ b/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/read_user.spec.ts @@ -6,10 +6,10 @@ */ import expect from '@kbn/expect'; -import { registry } from '../../../common/registry'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; export default function apiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmReadUser = getService('legacySupertestAsApmReadUser'); function getJobs() { diff --git a/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/write_user.ts b/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/write_user.spec.ts similarity index 98% rename from x-pack/test/apm_api_integration/tests/settings/anomaly_detection/write_user.ts rename to x-pack/test/apm_api_integration/tests/settings/anomaly_detection/write_user.spec.ts index 3d671c8fb825e..0bf4bec9ee8b1 100644 --- a/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/write_user.ts +++ b/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/write_user.spec.ts @@ -7,10 +7,10 @@ import expect from '@kbn/expect'; import { countBy } from 'lodash'; -import { registry } from '../../../common/registry'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; export default function apiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const legacyWriteUserClient = getService('legacySupertestAsApmWriteUser'); diff --git a/x-pack/test/apm_api_integration/tests/settings/custom_link.ts b/x-pack/test/apm_api_integration/tests/settings/custom_link.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/settings/custom_link.ts rename to x-pack/test/apm_api_integration/tests/settings/custom_link.spec.ts index 86f60be3fdc4c..aeb110dc1faf2 100644 --- a/x-pack/test/apm_api_integration/tests/settings/custom_link.ts +++ b/x-pack/test/apm_api_integration/tests/settings/custom_link.spec.ts @@ -8,10 +8,10 @@ import expect from '@kbn/expect'; import { CustomLink } from '../../../../plugins/apm/common/custom_link/custom_link_types'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; import { ApmApiError } from '../../common/apm_api_supertest'; export default function customLinksTests({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const log = getService('log'); diff --git a/x-pack/test/apm_api_integration/tests/suggestions/suggestions.ts b/x-pack/test/apm_api_integration/tests/suggestions/suggestions.spec.ts similarity index 98% rename from x-pack/test/apm_api_integration/tests/suggestions/suggestions.ts rename to x-pack/test/apm_api_integration/tests/suggestions/suggestions.spec.ts index d551aec632fab..0cd16e5652f65 100644 --- a/x-pack/test/apm_api_integration/tests/suggestions/suggestions.ts +++ b/x-pack/test/apm_api_integration/tests/suggestions/suggestions.spec.ts @@ -10,9 +10,9 @@ import { TRANSACTION_TYPE, } from '../../../../plugins/apm/common/elasticsearch_fieldnames'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function suggestionsTests({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const archiveName = 'apm_8.0.0'; diff --git a/x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.ts b/x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.ts rename to x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.spec.ts index 4cc9b2f0679fe..1b2c919f538a7 100644 --- a/x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.ts +++ b/x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.spec.ts @@ -10,10 +10,10 @@ import { meanBy, sumBy } from 'lodash'; import { BackendNode, ServiceNode } from '../../../../plugins/apm/common/connections'; import { PromiseReturnType } from '../../../../plugins/observability/typings/common'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; import { roundNumber } from '../../utils'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const synthtraceEsClient = getService('synthtraceEsClient'); diff --git a/x-pack/test/apm_api_integration/tests/throughput/service_apis.ts b/x-pack/test/apm_api_integration/tests/throughput/service_apis.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/throughput/service_apis.ts rename to x-pack/test/apm_api_integration/tests/throughput/service_apis.spec.ts index c4fffd8d79afb..7318fc449fcdb 100644 --- a/x-pack/test/apm_api_integration/tests/throughput/service_apis.ts +++ b/x-pack/test/apm_api_integration/tests/throughput/service_apis.spec.ts @@ -10,10 +10,10 @@ import { meanBy, sumBy } from 'lodash'; import { LatencyAggregationType } from '../../../../plugins/apm/common/latency_aggregation_types'; import { PromiseReturnType } from '../../../../plugins/observability/typings/common'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; import { roundNumber } from '../../utils'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const synthtraceEsClient = getService('synthtraceEsClient'); diff --git a/x-pack/test/apm_api_integration/tests/traces/__snapshots__/top_traces.snap b/x-pack/test/apm_api_integration/tests/traces/__snapshots__/top_traces.spec.snap similarity index 100% rename from x-pack/test/apm_api_integration/tests/traces/__snapshots__/top_traces.snap rename to x-pack/test/apm_api_integration/tests/traces/__snapshots__/top_traces.spec.snap diff --git a/x-pack/test/apm_api_integration/tests/traces/top_traces.ts b/x-pack/test/apm_api_integration/tests/traces/top_traces.spec.ts similarity index 98% rename from x-pack/test/apm_api_integration/tests/traces/top_traces.ts rename to x-pack/test/apm_api_integration/tests/traces/top_traces.spec.ts index 4968732f82203..51b14809982d8 100644 --- a/x-pack/test/apm_api_integration/tests/traces/top_traces.ts +++ b/x-pack/test/apm_api_integration/tests/traces/top_traces.spec.ts @@ -9,9 +9,9 @@ import expect from '@kbn/expect'; import { sortBy } from 'lodash'; import archives_metadata from '../../common/fixtures/es_archiver/archives_metadata'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); const archiveName = 'apm_8.0.0'; diff --git a/x-pack/test/apm_api_integration/tests/traces/trace_by_id.tsx b/x-pack/test/apm_api_integration/tests/traces/trace_by_id.spec.ts similarity index 98% rename from x-pack/test/apm_api_integration/tests/traces/trace_by_id.tsx rename to x-pack/test/apm_api_integration/tests/traces/trace_by_id.spec.ts index d99a2b95a792e..085fa3a122b4c 100644 --- a/x-pack/test/apm_api_integration/tests/traces/trace_by_id.tsx +++ b/x-pack/test/apm_api_integration/tests/traces/trace_by_id.spec.ts @@ -8,10 +8,10 @@ import expect from '@kbn/expect'; import archives_metadata from '../../common/fixtures/es_archiver/archives_metadata'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; import { createApmApiClient, SupertestReturnType } from '../../common/apm_api_supertest'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('supertest'); const apmApiSupertest = createApmApiClient(supertest); diff --git a/x-pack/test/apm_api_integration/tests/transactions/__snapshots__/breakdown.snap b/x-pack/test/apm_api_integration/tests/transactions/__snapshots__/breakdown.spec.snap similarity index 100% rename from x-pack/test/apm_api_integration/tests/transactions/__snapshots__/breakdown.snap rename to x-pack/test/apm_api_integration/tests/transactions/__snapshots__/breakdown.spec.snap diff --git a/x-pack/test/apm_api_integration/tests/transactions/__snapshots__/error_rate.snap b/x-pack/test/apm_api_integration/tests/transactions/__snapshots__/error_rate.spec.snap similarity index 100% rename from x-pack/test/apm_api_integration/tests/transactions/__snapshots__/error_rate.snap rename to x-pack/test/apm_api_integration/tests/transactions/__snapshots__/error_rate.spec.snap diff --git a/x-pack/test/apm_api_integration/tests/transactions/__snapshots__/latency.snap b/x-pack/test/apm_api_integration/tests/transactions/__snapshots__/latency.spec.snap similarity index 100% rename from x-pack/test/apm_api_integration/tests/transactions/__snapshots__/latency.snap rename to x-pack/test/apm_api_integration/tests/transactions/__snapshots__/latency.spec.snap diff --git a/x-pack/test/apm_api_integration/tests/transactions/__snapshots__/top_transaction_groups.snap b/x-pack/test/apm_api_integration/tests/transactions/__snapshots__/top_transaction_groups.spec.snap similarity index 100% rename from x-pack/test/apm_api_integration/tests/transactions/__snapshots__/top_transaction_groups.snap rename to x-pack/test/apm_api_integration/tests/transactions/__snapshots__/top_transaction_groups.spec.snap diff --git a/x-pack/test/apm_api_integration/tests/transactions/__snapshots__/transaction_charts.snap b/x-pack/test/apm_api_integration/tests/transactions/__snapshots__/transaction_charts.spec.snap similarity index 100% rename from x-pack/test/apm_api_integration/tests/transactions/__snapshots__/transaction_charts.snap rename to x-pack/test/apm_api_integration/tests/transactions/__snapshots__/transaction_charts.spec.snap diff --git a/x-pack/test/apm_api_integration/tests/transactions/__snapshots__/transactions_charts.snap b/x-pack/test/apm_api_integration/tests/transactions/__snapshots__/transactions_charts.spec.snap similarity index 100% rename from x-pack/test/apm_api_integration/tests/transactions/__snapshots__/transactions_charts.snap rename to x-pack/test/apm_api_integration/tests/transactions/__snapshots__/transactions_charts.spec.snap diff --git a/x-pack/test/apm_api_integration/tests/transactions/breakdown.ts b/x-pack/test/apm_api_integration/tests/transactions/breakdown.spec.ts similarity index 98% rename from x-pack/test/apm_api_integration/tests/transactions/breakdown.ts rename to x-pack/test/apm_api_integration/tests/transactions/breakdown.spec.ts index bc2e2f534a0bb..c24881b5c43f4 100644 --- a/x-pack/test/apm_api_integration/tests/transactions/breakdown.ts +++ b/x-pack/test/apm_api_integration/tests/transactions/breakdown.spec.ts @@ -8,9 +8,9 @@ import expect from '@kbn/expect'; import archives_metadata from '../../common/fixtures/es_archiver/archives_metadata'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); const archiveName = 'apm_8.0.0'; diff --git a/x-pack/test/apm_api_integration/tests/transactions/error_rate.ts b/x-pack/test/apm_api_integration/tests/transactions/error_rate.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/transactions/error_rate.ts rename to x-pack/test/apm_api_integration/tests/transactions/error_rate.spec.ts index aeb7cc61a582a..3a198d36e02e6 100644 --- a/x-pack/test/apm_api_integration/tests/transactions/error_rate.ts +++ b/x-pack/test/apm_api_integration/tests/transactions/error_rate.spec.ts @@ -12,12 +12,12 @@ import moment from 'moment'; import { APIReturnType } from '../../../../plugins/apm/public/services/rest/createCallApmApi'; import archives_metadata from '../../common/fixtures/es_archiver/archives_metadata'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; type ErrorRate = APIReturnType<'GET /internal/apm/services/{serviceName}/transactions/charts/error_rate'>; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); const archiveName = 'apm_8.0.0'; diff --git a/x-pack/test/apm_api_integration/tests/transactions/latency.ts b/x-pack/test/apm_api_integration/tests/transactions/latency.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/transactions/latency.ts rename to x-pack/test/apm_api_integration/tests/transactions/latency.spec.ts index beaff7647868a..6c69d09b45d62 100644 --- a/x-pack/test/apm_api_integration/tests/transactions/latency.ts +++ b/x-pack/test/apm_api_integration/tests/transactions/latency.spec.ts @@ -12,12 +12,12 @@ import { APIReturnType } from '../../../../plugins/apm/public/services/rest/crea import { PromiseReturnType } from '../../../../plugins/observability/typings/common'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import archives_metadata from '../../common/fixtures/es_archiver/archives_metadata'; -import { registry } from '../../common/registry'; type LatencyChartReturnType = APIReturnType<'GET /internal/apm/services/{serviceName}/transactions/charts/latency'>; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); const archiveName = 'apm_8.0.0'; diff --git a/x-pack/test/apm_api_integration/tests/transactions/latency_overall_distribution.ts b/x-pack/test/apm_api_integration/tests/transactions/latency_overall_distribution.spec.ts similarity index 97% rename from x-pack/test/apm_api_integration/tests/transactions/latency_overall_distribution.ts rename to x-pack/test/apm_api_integration/tests/transactions/latency_overall_distribution.spec.ts index b204f939020d7..ff1a49fb8fc54 100644 --- a/x-pack/test/apm_api_integration/tests/transactions/latency_overall_distribution.ts +++ b/x-pack/test/apm_api_integration/tests/transactions/latency_overall_distribution.spec.ts @@ -7,9 +7,9 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const endpoint = 'POST /internal/apm/latency/overall_distribution'; diff --git a/x-pack/test/apm_api_integration/tests/transactions/trace_samples.ts b/x-pack/test/apm_api_integration/tests/transactions/trace_samples.spec.ts similarity index 87% rename from x-pack/test/apm_api_integration/tests/transactions/trace_samples.ts rename to x-pack/test/apm_api_integration/tests/transactions/trace_samples.spec.ts index 19e75ff08fec2..ef114740ec735 100644 --- a/x-pack/test/apm_api_integration/tests/transactions/trace_samples.ts +++ b/x-pack/test/apm_api_integration/tests/transactions/trace_samples.spec.ts @@ -7,11 +7,13 @@ import expect from '@kbn/expect'; import qs from 'querystring'; +import { sortBy } from 'lodash'; +import { APIReturnType } from '../../../../plugins/apm/public/services/rest/createCallApmApi'; import archives_metadata from '../../common/fixtures/es_archiver/archives_metadata'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); const archiveName = 'apm_8.0.0'; @@ -31,11 +33,13 @@ export default function ApiTest({ getService }: FtrProviderContext) { { config: 'basic', archives: [] }, () => { it('handles empty state', async () => { - const response = await supertest.get(url); + const response: { + body: APIReturnType<'GET /internal/apm/services/{serviceName}/transactions/traces/samples'>; + status: number; + } = await supertest.get(url); expect(response.status).to.be(200); - expect(response.body.noHits).to.be(true); expect(response.body.traceSamples.length).to.be(0); }); } @@ -45,14 +49,17 @@ export default function ApiTest({ getService }: FtrProviderContext) { 'Transaction trace samples response structure when data is loaded', { config: 'basic', archives: [archiveName] }, () => { - let response: any; + let response: { + body: APIReturnType<'GET /internal/apm/services/{serviceName}/transactions/traces/samples'>; + status: number; + }; + before(async () => { response = await supertest.get(url); }); it('returns the correct metadata', () => { expect(response.status).to.be(200); - expect(response.body.noHits).to.be(false); expect(response.body.traceSamples.length).to.be.greaterThan(0); }); @@ -63,43 +70,51 @@ export default function ApiTest({ getService }: FtrProviderContext) { it('returns the correct samples', () => { const { traceSamples } = response.body; - expectSnapshot(traceSamples.sort((sample: any) => sample.traceId)).toMatchInline(` + expectSnapshot(sortBy(traceSamples, (sample) => sample.traceId)).toMatchInline(` Array [ Object { - "traceId": "5267685738bf75b68b16bf3426ba858c", - "transactionId": "5223f43bc3154c5a", + "traceId": "0996b09e42ad4dbfaaa6a069326c6e66", + "transactionId": "5721364b179716d0", }, Object { - "traceId": "9a84d15e5a0e32098d569948474e8e2f", - "transactionId": "b85db78a9824107b", + "traceId": "10d882b7118870015815a27c37892375", + "transactionId": "0cf9db0b1e321239", }, Object { - "traceId": "e123f0466fa092f345d047399db65aa2", - "transactionId": "c0af16286229d811", + "traceId": "2ca82e99453c58584c4b8de9a8ba4ec3", + "transactionId": "8fa2ca73976ce1e7", + }, + Object { + "traceId": "45b3d1a86003938687a55e49bf3610b8", + "transactionId": "a707456bda99ee98", }, Object { "traceId": "4943691f87b7eb97d442d1ef33ca65c7", "transactionId": "f6f4677d731e57c5", }, Object { - "traceId": "66bd97c457f5675665397ac9201cc050", - "transactionId": "592b60cc9ddabb15", + "traceId": "5267685738bf75b68b16bf3426ba858c", + "transactionId": "5223f43bc3154c5a", }, Object { - "traceId": "10d882b7118870015815a27c37892375", - "transactionId": "0cf9db0b1e321239", + "traceId": "66bd97c457f5675665397ac9201cc050", + "transactionId": "592b60cc9ddabb15", }, Object { "traceId": "6d85d8f1bc4bbbfdb19cdba59d2fc164", "transactionId": "d0a16f0f52f25d6b", }, Object { - "traceId": "0996b09e42ad4dbfaaa6a069326c6e66", - "transactionId": "5721364b179716d0", + "traceId": "7483bd52150d1c93a858c60bfdd0c138", + "transactionId": "e20e701ff93bdb55", }, Object { - "traceId": "d9415d102c0634e1e8fa53ceef07be70", - "transactionId": "fab91c68c9b1c42b", + "traceId": "9a84d15e5a0e32098d569948474e8e2f", + "transactionId": "b85db78a9824107b", + }, + Object { + "traceId": "a21ea39b41349a4614a86321d965c957", + "transactionId": "338bd7908cbf7f2d", }, Object { "traceId": "ca7a2072e7974ae84b5096706c6b6255", @@ -110,20 +125,12 @@ export default function ApiTest({ getService }: FtrProviderContext) { "transactionId": "6fcd12599c1b57fa", }, Object { - "traceId": "2ca82e99453c58584c4b8de9a8ba4ec3", - "transactionId": "8fa2ca73976ce1e7", - }, - Object { - "traceId": "45b3d1a86003938687a55e49bf3610b8", - "transactionId": "a707456bda99ee98", - }, - Object { - "traceId": "7483bd52150d1c93a858c60bfdd0c138", - "transactionId": "e20e701ff93bdb55", + "traceId": "d9415d102c0634e1e8fa53ceef07be70", + "transactionId": "fab91c68c9b1c42b", }, Object { - "traceId": "a21ea39b41349a4614a86321d965c957", - "transactionId": "338bd7908cbf7f2d", + "traceId": "e123f0466fa092f345d047399db65aa2", + "transactionId": "c0af16286229d811", }, ] `); diff --git a/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.ts b/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.ts rename to x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.spec.ts index e877afc070050..72a0cdbbee48f 100644 --- a/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.ts +++ b/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.spec.ts @@ -12,13 +12,13 @@ import { LatencyAggregationType } from '../../../../plugins/apm/common/latency_a import { asPercent } from '../../../../plugins/apm/common/utils/formatters'; import { APIReturnType } from '../../../../plugins/apm/public/services/rest/createCallApmApi'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { registry } from '../../common/registry'; import { roundNumber } from '../../utils'; type TransactionsGroupsDetailedStatistics = APIReturnType<'GET /internal/apm/services/{serviceName}/transactions/groups/detailed_statistics'>; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const synthtraceEsClient = getService('synthtraceEsClient'); diff --git a/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_main_statistics.ts b/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_main_statistics.spec.ts similarity index 99% rename from x-pack/test/apm_api_integration/tests/transactions/transactions_groups_main_statistics.ts rename to x-pack/test/apm_api_integration/tests/transactions/transactions_groups_main_statistics.spec.ts index 7664d28271e14..2c645ce2c6277 100644 --- a/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_main_statistics.ts +++ b/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_main_statistics.spec.ts @@ -11,12 +11,12 @@ import url from 'url'; import { APIReturnType } from '../../../../plugins/apm/public/services/rest/createCallApmApi'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import archives from '../../common/fixtures/es_archiver/archives_metadata'; -import { registry } from '../../common/registry'; type TransactionsGroupsPrimaryStatistics = APIReturnType<'GET /internal/apm/services/{serviceName}/transactions/groups/main_statistics'>; export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); const supertest = getService('legacySupertestAsApmReadUser'); const archiveName = 'apm_8.0.0'; diff --git a/x-pack/test/examples/reporting_examples/capture_test.ts b/x-pack/test/examples/reporting_examples/capture_test.ts index 62460bd140bba..16162a15c3121 100644 --- a/x-pack/test/examples/reporting_examples/capture_test.ts +++ b/x-pack/test/examples/reporting_examples/capture_test.ts @@ -44,48 +44,5 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await compareImages.checkIfPngsMatch(pngSessionFilePath, fixtures.baselineAPng) ).to.be.lessThan(0.09); }); - - it('PDF that matches the baseline', async () => { - await PageObjects.common.navigateToApp(appId); - - await (await testSubjects.find('shareButton')).click(); - await (await testSubjects.find('captureTestPanel')).click(); - await (await testSubjects.find('captureTestPDF')).click(); - - await PageObjects.reporting.clickGenerateReportButton(); - const url = await PageObjects.reporting.getReportURL(60000); - const captureData = await PageObjects.reporting.getRawPdfReportData(url); - - const pdfSessionFilePath = await compareImages.writeToSessionFile( - 'capture_test_baseline_a', - captureData - ); - - expect( - await compareImages.checkIfPdfsMatch(pdfSessionFilePath, fixtures.baselineAPdf) - ).to.be.lessThan(0.001); - }); - - it('print-optimized PDF that matches the baseline', async () => { - await PageObjects.common.navigateToApp(appId); - - await (await testSubjects.find('shareButton')).click(); - await (await testSubjects.find('captureTestPanel')).click(); - await (await testSubjects.find('captureTestPDFPrint')).click(); - - await PageObjects.reporting.checkUsePrintLayout(); - await PageObjects.reporting.clickGenerateReportButton(); - const url = await PageObjects.reporting.getReportURL(60000); - const captureData = await PageObjects.reporting.getRawPdfReportData(url); - - const pdfSessionFilePath = await compareImages.writeToSessionFile( - 'capture_test_baseline_a', - captureData - ); - - expect( - await compareImages.checkIfPdfsMatch(pdfSessionFilePath, fixtures.baselineAPdfPrint) - ).to.be.lessThan(0.001); - }); }); } diff --git a/x-pack/test/fleet_api_integration/apis/package_policy/upgrade.ts b/x-pack/test/fleet_api_integration/apis/package_policy/upgrade.ts index a61a77fd37f6b..5a61d69ed8ba6 100644 --- a/x-pack/test/fleet_api_integration/apis/package_policy/upgrade.ts +++ b/x-pack/test/fleet_api_integration/apis/package_policy/upgrade.ts @@ -570,16 +570,14 @@ export default function (providerContext: FtrProviderContext) { describe('upgrade', function () { it('fails to upgrade package policy', async function () { - const { body }: { body: UpgradePackagePolicyResponse } = await supertest + await supertest .post(`/api/fleet/package_policies/upgrade`) .set('kbn-xsrf', 'xxxx') .send({ packagePolicyIds: [packagePolicyId], dryRun: false, }) - .expect(200); - - expect(body[0].success).to.be(false); + .expect(400); }); }); }); @@ -672,16 +670,14 @@ export default function (providerContext: FtrProviderContext) { describe('upgrade', function () { it('fails to upgrade package policy', async function () { - const { body }: { body: UpgradePackagePolicyResponse } = await supertest + await supertest .post(`/api/fleet/package_policies/upgrade`) .set('kbn-xsrf', 'xxxx') .send({ packagePolicyIds: [packagePolicyId], dryRun: false, }) - .expect(200); - - expect(body[0].success).to.be(false); + .expect(400); }); }); }); diff --git a/x-pack/test/functional/apps/canvas/index.js b/x-pack/test/functional/apps/canvas/index.js index bf51a326d460d..e6727e177c3e3 100644 --- a/x-pack/test/functional/apps/canvas/index.js +++ b/x-pack/test/functional/apps/canvas/index.js @@ -29,5 +29,6 @@ export default function canvasApp({ loadTestFile, getService }) { loadTestFile(require.resolve('./feature_controls/canvas_spaces')); loadTestFile(require.resolve('./lens')); loadTestFile(require.resolve('./reports')); + loadTestFile(require.resolve('./saved_object_resolve')); }); } diff --git a/x-pack/test/functional/apps/canvas/saved_object_resolve.ts b/x-pack/test/functional/apps/canvas/saved_object_resolve.ts new file mode 100644 index 0000000000000..107701b6c42f4 --- /dev/null +++ b/x-pack/test/functional/apps/canvas/saved_object_resolve.ts @@ -0,0 +1,131 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function canvasFiltersTest({ getService, getPageObjects }: FtrProviderContext) { + const testSubjects = getService('testSubjects'); + const retry = getService('retry'); + const PageObjects = getPageObjects(['canvas', 'common']); + const find = getService('find'); + const kibanaServer = getService('kibanaServer'); + const spacesService = getService('spaces'); + const archive = 'x-pack/test/functional/fixtures/kbn_archiver/canvas/saved_object_resolve'; + const browser = getService('browser'); + + describe('filters', function () { + // there is an issue with FF not properly clicking on workpad elements + this.tags('skipFirefox'); + + before(async () => { + await spacesService.create({ + id: 'custom_space', + name: 'custom_space', + disabledFeatures: [], + }); + + await kibanaServer.importExport.load(archive, { space: 'custom_space' }); + + // Create alias match + await kibanaServer.savedObjects.create({ + type: 'legacy-url-alias', + id: 'custom_space:canvas-workpad:workpad-1705f884-6224-47de-ba49-ca224fe6ec31-old-id', + overwrite: true, + attributes: { + targetType: 'canvas-workpad', + targetId: 'workpad-1705f884-6224-47de-ba49-ca224fe6ec31-new-id', + targetNamespace: 'custom_space', + sourceId: 'workpad-1705f884-6224-47de-ba49-ca224fe6ec31-old-id', + }, + references: [], + }); + + // Create conflict match + await kibanaServer.savedObjects.create({ + type: 'legacy-url-alias', + id: 'custom_space:canvas-workpad:workpad-1705f884-6224-47de-ba49-ca224fe6ec31-conflict-old', + overwrite: true, + attributes: { + targetType: 'canvas-workpad', + targetId: 'workpad-1705f884-6224-47de-ba49-ca224fe6ec31-conflict-new', + targetNamespace: 'custom_space', + sourceId: 'workpad-1705f884-6224-47de-ba49-ca224fe6ec31-conflict-old', + }, + references: [], + }); + }); + + after(async () => { + await kibanaServer.savedObjects.bulkDelete({ + objects: [ + { + type: 'legacy-url-alias', + id: 'custom_space:canvas-workpad:workpad-1705f884-6224-47de-ba49-ca224fe6ec31-old-id', + }, + { + type: 'legacy-url-alias', + id: 'custom_space:canvas-workpad:workpad-1705f884-6224-47de-ba49-ca224fe6ec31-conflict-old', + }, + ], + }); + await kibanaServer.importExport.unload(archive, { space: 'custom_space' }); + await spacesService.delete('custom_space'); + }); + + it('redirects an alias match', async () => { + await PageObjects.common.navigateToApp('canvas', { + basePath: '/s/custom_space', + hash: '/workpad/workpad-1705f884-6224-47de-ba49-ca224fe6ec31-old-id/page/1', + }); + + // Wait for the redirect toast + await retry.try(async () => { + const text = await ( + await find.byCssSelector('.euiGlobalToastList .euiToast .euiText') + ).getVisibleText(); + + expect(text.includes("The Workpad you're looking for has a new location.")).to.be(true); + }); + + const currentUrl = await browser.getCurrentUrl(); + + expect( + currentUrl.includes('/workpad/workpad-1705f884-6224-47de-ba49-ca224fe6ec31-new-id') + ).to.be(true); + + await retry.try(async () => { + const elements = await testSubjects.findAll( + 'canvasWorkpadPage > canvasWorkpadPageElementContent' + ); + expect(elements).to.have.length(4); + }); + }); + + it('handles a conflict match', async () => { + await PageObjects.common.navigateToApp('canvas', { + basePath: '/s/custom_space', + hash: '/workpad/workpad-1705f884-6224-47de-ba49-ca224fe6ec31-conflict-old/page/1', + }); + + await testSubjects.click('legacy-url-conflict-go-to-other-button'); + + const currentUrl = await browser.getCurrentUrl(); + expect( + currentUrl.includes('/workpad/workpad-1705f884-6224-47de-ba49-ca224fe6ec31-conflict-new') + ).to.be(true); + + // Conflict workpad has no elements, so let's make sure the new one is rendered with it's elements + await retry.try(async () => { + const elements = await testSubjects.findAll( + 'canvasWorkpadPage > canvasWorkpadPageElementContent' + ); + expect(elements).to.have.length(4); + }); + }); + }); +} diff --git a/x-pack/test/functional/apps/discover/value_suggestions_non_timebased.ts b/x-pack/test/functional/apps/discover/value_suggestions_non_timebased.ts index e8cc34604eaba..ecf8fd31ce932 100644 --- a/x-pack/test/functional/apps/discover/value_suggestions_non_timebased.ts +++ b/x-pack/test/functional/apps/discover/value_suggestions_non_timebased.ts @@ -11,10 +11,10 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const queryBar = getService('queryBar'); - const PageObjects = getPageObjects(['common', 'settings', 'context']); + const retry = getService('retry'); + const PageObjects = getPageObjects(['common', 'settings', 'context', 'header']); - // FLAKY: https://github.com/elastic/kibana/issues/114745 - describe.skip('value suggestions non time based', function describeIndexTests() { + describe('value suggestions non time based', function describeIndexTests() { before(async function () { await esArchiver.loadIfNeeded( 'test/functional/fixtures/es_archiver/index_pattern_without_timefield' @@ -29,11 +29,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('shows all autosuggest options for a filter in discover context app', async () => { await PageObjects.common.navigateToApp('discover'); - await queryBar.setQuery('type.keyword : '); - const suggestions = await queryBar.getSuggestions(); - expect(suggestions.length).to.be(1); - expect(suggestions).to.contain('"apache"'); + + await retry.try(async () => { + const suggestions = await queryBar.getSuggestions(); + expect(suggestions.length).to.be(1); + expect(suggestions).to.contain('"apache"'); + }); }); }); } diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index.ts b/x-pack/test/functional/apps/ml/data_visualizer/index.ts index c1e5d0b4b6aae..3bb8e3d728318 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/index.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/index.ts @@ -13,6 +13,7 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./index_data_visualizer')); loadTestFile(require.resolve('./index_data_visualizer_grid_in_discover')); + loadTestFile(require.resolve('./index_data_visualizer_grid_in_dashboard')); loadTestFile(require.resolve('./index_data_visualizer_actions_panel')); loadTestFile(require.resolve('./index_data_visualizer_index_pattern_management')); loadTestFile(require.resolve('./file_data_visualizer')); diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts index ff0d489293682..bcdf978d46cad 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts @@ -9,6 +9,7 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { TestData, MetricFieldVisConfig } from './types'; import { farequoteDataViewTestData, + farequoteKQLFiltersSearchTestData, farequoteKQLSearchTestData, farequoteLuceneSearchTestData, sampleLogTestData, @@ -76,6 +77,13 @@ export default function ({ getService }: FtrProviderContext) { ); await ml.dataVisualizerIndexBased.assertTotalFieldsCount(testData.expected.totalFieldsCount); + if (testData.expected.filters) { + await ml.testExecution.logTestStep('displays filters in filter bar correctly'); + for (const filter of testData.expected.filters!) { + await ml.dataVisualizerIndexBased.assertFilterBarFilterContent(filter); + } + } + await ml.testExecution.logTestStep( 'displays details for metric fields and non-metric fields correctly' ); @@ -96,7 +104,9 @@ export default function ({ getService }: FtrProviderContext) { fieldRow.fieldName!, fieldRow.docCountFormatted, fieldRow.exampleCount, - fieldRow.viewableInLens + fieldRow.viewableInLens, + false, + fieldRow.exampleContent ); } @@ -150,6 +160,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.testResources.createIndexPatternIfNeeded('ft_module_sample_logs', '@timestamp'); await ml.testResources.createSavedSearchFarequoteLuceneIfNeeded(); await ml.testResources.createSavedSearchFarequoteKueryIfNeeded(); + await ml.testResources.createSavedSearchFarequoteFilterAndKueryIfNeeded(); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.securityUI.loginAsMlPowerUser(); @@ -182,6 +193,14 @@ export default function ({ getService }: FtrProviderContext) { }); runTests(farequoteLuceneSearchTestData); + + it(`${farequoteKQLFiltersSearchTestData.suiteTitle} loads the data visualizer selector page`, async () => { + // Start navigation from the base of the ML app. + await ml.navigation.navigateToMl(); + await ml.navigation.navigateToDataVisualizer(); + }); + + runTests(farequoteKQLFiltersSearchTestData); }); describe('with module_sample_logs ', function () { diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_dashboard.ts b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_dashboard.ts new file mode 100644 index 0000000000000..97c6c06bc3225 --- /dev/null +++ b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_dashboard.ts @@ -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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../../ftr_provider_context'; +import { TestData, MetricFieldVisConfig } from './types'; +import { farequoteLuceneFiltersSearchTestData } from './index_test_data'; + +const SHOW_FIELD_STATISTICS = 'discover:showFieldStatistics'; +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const esArchiver = getService('esArchiver'); + const PageObjects = getPageObjects(['common', 'discover', 'timePicker', 'settings', 'dashboard']); + const ml = getService('ml'); + const retry = getService('retry'); + const dashboardAddPanel = getService('dashboardAddPanel'); + + function runTests(testData: TestData) { + const savedSearchTitle = `Field stats for ${testData.suiteTitle} ${Date.now()}`; + const dashboardTitle = `Dashboard for ${testData.suiteTitle} ${Date.now()}`; + const startTime = 'Jan 1, 2016 @ 00:00:00.000'; + const endTime = 'Nov 1, 2020 @ 00:00:00.000'; + + describe(`with ${testData.suiteTitle}`, function () { + after(async function () { + await ml.testResources.deleteSavedSearchByTitle(savedSearchTitle); + await ml.testResources.deleteDashboardByTitle(dashboardTitle); + }); + + it(`saves search with Field statistics table in Discover`, async function () { + await ml.testResources.setAdvancedSettingProperty(SHOW_FIELD_STATISTICS, true); + + await PageObjects.common.navigateToApp('discover'); + if (testData.isSavedSearch) { + await retry.tryForTime(2 * 1000, async () => { + await PageObjects.discover.loadSavedSearch(testData.sourceIndexOrSavedSearch); + }); + } else { + await ml.dashboardEmbeddables.selectDiscoverIndexPattern( + testData.sourceIndexOrSavedSearch + ); + } + await PageObjects.timePicker.setAbsoluteRange(startTime, endTime); + + await PageObjects.discover.assertViewModeToggleExists(); + await PageObjects.discover.clickViewModeFieldStatsButton(); + await ml.testExecution.logTestStep('saves as new search'); + await PageObjects.discover.saveSearch(savedSearchTitle, true); + }); + + it(`displays Field statistics table in Dashboard when enabled`, async function () { + await PageObjects.common.navigateToApp('dashboard'); + await PageObjects.dashboard.gotoDashboardLandingPage(); + await PageObjects.dashboard.clickNewDashboard(); + await dashboardAddPanel.addSavedSearch(savedSearchTitle); + await PageObjects.dashboard.waitForRenderComplete(); + + await PageObjects.timePicker.setAbsoluteRange(startTime, endTime); + await PageObjects.dashboard.waitForRenderComplete(); + + for (const fieldRow of testData.expected.metricFields as Array< + Required + >) { + await ml.dataVisualizerTable.assertNumberFieldContents( + fieldRow.fieldName, + fieldRow.docCountFormatted, + fieldRow.topValuesCount, + fieldRow.viewableInLens + ); + } + + for (const fieldRow of testData.expected.nonMetricFields!) { + await ml.dataVisualizerTable.assertNonMetricFieldContents( + fieldRow.type, + fieldRow.fieldName!, + fieldRow.docCountFormatted, + fieldRow.exampleCount, + fieldRow.viewableInLens, + false, + fieldRow.exampleContent + ); + } + + await PageObjects.dashboard.saveDashboard(dashboardTitle); + }); + + it(`doesn't display Field statistics table in Dashboard when disabled`, async function () { + await ml.testResources.setAdvancedSettingProperty(SHOW_FIELD_STATISTICS, false); + + await PageObjects.common.navigateToApp('dashboard'); + await PageObjects.dashboard.gotoDashboardEditMode(dashboardTitle); + await PageObjects.dashboard.waitForRenderComplete(); + + await dashboardAddPanel.addSavedSearch(savedSearchTitle); + await PageObjects.dashboard.waitForRenderComplete(); + + await PageObjects.timePicker.setAbsoluteRange(startTime, endTime); + await PageObjects.dashboard.waitForRenderComplete(); + + await PageObjects.discover.assertFieldStatsTableNotExists(); + await PageObjects.dashboard.saveDashboard(dashboardTitle); + }); + }); + } + + describe('field statistics in Dashboard', function () { + before(async function () { + await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); + await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createSavedSearchFarequoteFilterAndLuceneIfNeeded(); + await ml.securityUI.loginAsMlPowerUser(); + }); + + after(async function () { + await ml.testResources.clearAdvancedSettingProperty(SHOW_FIELD_STATISTICS); + }); + + runTests(farequoteLuceneFiltersSearchTestData); + }); +} diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_discover.ts b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_discover.ts index ba24684e13036..fff2c6fdbf232 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_discover.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_discover.ts @@ -5,7 +5,6 @@ * 2.0. */ -import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { TestData, MetricFieldVisConfig } from './types'; @@ -22,39 +21,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const PageObjects = getPageObjects(['common', 'discover', 'timePicker', 'settings']); const ml = getService('ml'); - const testSubjects = getService('testSubjects'); const retry = getService('retry'); - const toasts = getService('toasts'); - const selectIndexPattern = async (indexPattern: string) => { - await retry.tryForTime(2 * 1000, async () => { - await PageObjects.discover.selectIndexPattern(indexPattern); - const indexPatternTitle = await testSubjects.getVisibleText('indexPattern-switch-link'); - expect(indexPatternTitle).to.be(indexPattern); - }); - }; - - const clearAdvancedSetting = async (propertyName: string) => { - await retry.tryForTime(2 * 1000, async () => { - await PageObjects.common.navigateToUrl('management', 'kibana/settings', { - shouldUseHashForSubUrl: false, - }); - if ((await PageObjects.settings.getAdvancedSettingCheckbox(propertyName)) === 'true') { - await PageObjects.settings.clearAdvancedSettings(propertyName); - } - }); - }; - - const setAdvancedSettingCheckbox = async (propertyName: string, checkedState: boolean) => { - await retry.tryForTime(2 * 1000, async () => { - await PageObjects.common.navigateToUrl('management', 'kibana/settings', { - shouldUseHashForSubUrl: false, - }); - await testSubjects.click('settings'); - await toasts.dismissAllToasts(); - await PageObjects.settings.toggleAdvancedSettingCheckbox(propertyName, checkedState); - }); - }; + const startTime = 'Jan 1, 2016 @ 00:00:00.000'; + const endTime = 'Nov 1, 2020 @ 00:00:00.000'; function runTestsWhenDisabled(testData: TestData) { it('should not show view mode toggle or Field stats table', async function () { @@ -64,13 +34,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.discover.loadSavedSearch(testData.sourceIndexOrSavedSearch); }); } else { - await selectIndexPattern(testData.sourceIndexOrSavedSearch); + await ml.dashboardEmbeddables.selectDiscoverIndexPattern(testData.sourceIndexOrSavedSearch); } - await PageObjects.timePicker.setAbsoluteRange( - 'Jan 1, 2016 @ 00:00:00.000', - 'Nov 1, 2020 @ 00:00:00.000' - ); + await PageObjects.timePicker.setAbsoluteRange(startTime, endTime); await PageObjects.discover.assertViewModeToggleNotExists(); await PageObjects.discover.assertFieldStatsTableNotExists(); @@ -86,12 +53,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.discover.loadSavedSearch(testData.sourceIndexOrSavedSearch); }); } else { - await selectIndexPattern(testData.sourceIndexOrSavedSearch); + await ml.dashboardEmbeddables.selectDiscoverIndexPattern( + testData.sourceIndexOrSavedSearch + ); } - await PageObjects.timePicker.setAbsoluteRange( - 'Jan 1, 2016 @ 00:00:00.000', - 'Nov 1, 2020 @ 00:00:00.000' - ); + await PageObjects.timePicker.setAbsoluteRange(startTime, endTime); await PageObjects.discover.assertHitCount(testData.expected.totalDocCountFormatted); await PageObjects.discover.assertViewModeToggleExists(); @@ -140,16 +106,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); after(async function () { - await clearAdvancedSetting(SHOW_FIELD_STATISTICS); + await ml.testResources.clearAdvancedSettingProperty(SHOW_FIELD_STATISTICS); }); describe('when enabled', function () { before(async function () { - await setAdvancedSettingCheckbox(SHOW_FIELD_STATISTICS, true); + await ml.testResources.setAdvancedSettingProperty(SHOW_FIELD_STATISTICS, true); }); after(async function () { - await clearAdvancedSetting(SHOW_FIELD_STATISTICS); + await ml.testResources.clearAdvancedSettingProperty(SHOW_FIELD_STATISTICS); }); runTests(farequoteDataViewTestData); @@ -163,7 +129,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('when disabled', function () { before(async function () { // Ensure that the setting is set to default state which is false - await setAdvancedSettingCheckbox(SHOW_FIELD_STATISTICS, false); + await ml.testResources.setAdvancedSettingProperty(SHOW_FIELD_STATISTICS, false); }); runTestsWhenDisabled(farequoteDataViewTestData); diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index_test_data.ts b/x-pack/test/functional/apps/ml/data_visualizer/index_test_data.ts index 6dd782487fdf8..b4279e9c2c440 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/index_test_data.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/index_test_data.ts @@ -213,6 +213,7 @@ export const farequoteKQLFiltersSearchTestData: TestData = { { size: 5000, expected: { field: '@timestamp', docCountFormatted: '5000 (100%)' } }, ], expected: { + filters: [{ key: 'airline', value: 'ASA' }], totalDocCountFormatted: '5,674', metricFields: [ { @@ -408,6 +409,7 @@ export const farequoteLuceneFiltersSearchTestData: TestData = { { size: 5000, expected: { field: '@timestamp', docCountFormatted: '5000 (100%)' } }, ], expected: { + filters: [{ key: 'airline', value: 'ASA' }], totalDocCountFormatted: '5,673', metricFields: [ { diff --git a/x-pack/test/functional/apps/ml/data_visualizer/types.ts b/x-pack/test/functional/apps/ml/data_visualizer/types.ts index 5c3f890dba561..dc38bc31f568b 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/types.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/types.ts @@ -33,6 +33,13 @@ export interface TestData { expected: { field: string; docCountFormatted: string }; }>; expected: { + filters?: Array<{ + key: string; + value: string; + enabled?: boolean; + pinned?: boolean; + negated?: boolean; + }>; totalDocCountFormatted: string; metricFields?: MetricFieldVisConfig[]; nonMetricFields?: NonMetricFieldVisConfig[]; diff --git a/x-pack/test/functional/apps/saved_objects_management/feature_controls/saved_objects_management_security.ts b/x-pack/test/functional/apps/saved_objects_management/feature_controls/saved_objects_management_security.ts index 58f08a1dfb9f7..0eaf4893e072d 100644 --- a/x-pack/test/functional/apps/saved_objects_management/feature_controls/saved_objects_management_security.ts +++ b/x-pack/test/functional/apps/saved_objects_management/feature_controls/saved_objects_management_security.ts @@ -231,7 +231,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { // From https://github.com/elastic/kibana/issues/59588 edit view became read-only json view // test description changed from "edit" to "inspect" // Skipping the test to allow code owners to delete or modify the test. - describe('inspect visualization', () => { + // + // FLAKY: https://github.com/elastic/kibana/issues/116048 + describe.skip('inspect visualization', () => { before(async () => { await PageObjects.settings.navigateTo(); await PageObjects.settings.clickKibanaSavedObjects(); diff --git a/x-pack/test/functional/fixtures/kbn_archiver/canvas/saved_object_resolve.json b/x-pack/test/functional/fixtures/kbn_archiver/canvas/saved_object_resolve.json new file mode 100644 index 0000000000000..24746ebe916ab --- /dev/null +++ b/x-pack/test/functional/fixtures/kbn_archiver/canvas/saved_object_resolve.json @@ -0,0 +1,282 @@ +{ + "attributes": { + "@created": "2018-11-19T19:17:12.646Z", + "@timestamp": "2018-11-19T19:36:28.499Z", + "assets": {}, + "colors": [ + "#37988d", + "#c19628", + "#b83c6f", + "#3f9939", + "#1785b0", + "#ca5f35", + "#45bdb0", + "#f2bc33", + "#e74b8b", + "#4fbf48", + "#1ea6dc", + "#fd7643", + "#72cec3", + "#f5cc5d", + "#ec77a8", + "#7acf74", + "#4cbce4", + "#fd986f", + "#a1ded7", + "#f8dd91", + "#f2a4c5", + "#a6dfa2", + "#86d2ed", + "#fdba9f", + "#000000", + "#444444", + "#777777", + "#BBBBBB", + "#FFFFFF", + "rgba(255,255,255,0)" + ], + "height": 920, + "isWriteable": true, + "name": "Alias Match Workpad", + "page": 0, + "pages": [ + { + "elements": [ + { + "expression": "markdown \n \"### Welcome to Canvas\n\nEnjoy your stay!\n\n- Green: Markdown, Browser function\n- Blue: SQL, Server function\n- Pink: CSV, Common function\n- Orange: Timelion, Server function\"\n| render \n containerStyle={containerStyle padding=\"8px\" opacity=\"1\" backgroundColor=\"#7acf74\"}", + "id": "element-8f64a10a-01f3-4a71-a682-5b627cbe4d0e", + "position": { + "angle": 0, + "height": 238, + "left": 33.5, + "top": 20, + "width": 338 + } + }, + { + "expression": "filters\n| essql query=\"SELECT extension,bytes FROM \\\"logstash*\\\" LIMIT 10\"\n| table\n| render \n containerStyle={containerStyle padding=\"4px\" opacity=\"0.7\" backgroundColor=\"#4cbce4\"}", + "id": "element-d3bf91e2-7e8c-4884-942e-d4e9006aef09", + "position": { + "angle": 0, + "height": 345, + "left": 439, + "top": 20, + "width": 367 + } + }, + { + "expression": "csv \"desc,price\nred fish,100\nblue fish,200\"\n| render \n containerStyle={containerStyle backgroundColor=\"#ec77a8\" padding=\"4px\" opacity=\"0.7\"}", + "id": "element-223fe2b3-ffb4-4070-ae61-3e06b8052abb", + "position": { + "angle": 0, + "height": 132, + "left": 25, + "top": 390, + "width": 207 + } + }, + { + "expression": "filters\n| timelion query=\".es(index=logstash*,q=extension:jpg)\" interval=\"1M\" from=\"2017-01-01\" to=\"2017-12-31\"\n| table perPage=200\n| render containerStyle={containerStyle backgroundColor=\"#fd986f\" opacity=\"0.7\"}", + "id": "element-3c905696-8258-4e9c-ab58-89018681f79f", + "position": { + "angle": 0, + "height": 397, + "left": 263.5, + "top": 390, + "width": 533 + } + } + ], + "id": "page-c38cd459-10fe-45f9-847b-2cbd7ec74319", + "style": { + "background": "#fff" + }, + "transition": {} + } + ], + "width": 840 + }, + "coreMigrationVersion": "7.15.0", + "id": "workpad-1705f884-6224-47de-ba49-ca224fe6ec31-new-id", + "migrationVersion": { + "canvas-workpad": "7.0.0" + }, + "references": [], + "type": "canvas-workpad", + "updated_at": "2018-11-19T19:36:28.511Z", + "version": "WzUsMl0=" +} + +{ + "attributes": { + "@created": "2018-11-19T19:17:12.646Z", + "@timestamp": "2018-11-19T19:36:28.499Z", + "assets": {}, + "colors": [ + "#37988d", + "#c19628", + "#b83c6f", + "#3f9939", + "#1785b0", + "#ca5f35", + "#45bdb0", + "#f2bc33", + "#e74b8b", + "#4fbf48", + "#1ea6dc", + "#fd7643", + "#72cec3", + "#f5cc5d", + "#ec77a8", + "#7acf74", + "#4cbce4", + "#fd986f", + "#a1ded7", + "#f8dd91", + "#f2a4c5", + "#a6dfa2", + "#86d2ed", + "#fdba9f", + "#000000", + "#444444", + "#777777", + "#BBBBBB", + "#FFFFFF", + "rgba(255,255,255,0)" + ], + "height": 920, + "isWriteable": true, + "name": "Conflict Alternate Workpad", + "page": 0, + "pages": [ + { + "elements": [ + { + "expression": "markdown \n \"### Welcome to Canvas\n\nEnjoy your stay!\n\n- Green: Markdown, Browser function\n- Blue: SQL, Server function\n- Pink: CSV, Common function\n- Orange: Timelion, Server function\"\n| render \n containerStyle={containerStyle padding=\"8px\" opacity=\"1\" backgroundColor=\"#7acf74\"}", + "id": "element-8f64a10a-01f3-4a71-a682-5b627cbe4d0e", + "position": { + "angle": 0, + "height": 238, + "left": 33.5, + "top": 20, + "width": 338 + } + }, + { + "expression": "filters\n| essql query=\"SELECT extension,bytes FROM \\\"logstash*\\\" LIMIT 10\"\n| table\n| render \n containerStyle={containerStyle padding=\"4px\" opacity=\"0.7\" backgroundColor=\"#4cbce4\"}", + "id": "element-d3bf91e2-7e8c-4884-942e-d4e9006aef09", + "position": { + "angle": 0, + "height": 345, + "left": 439, + "top": 20, + "width": 367 + } + }, + { + "expression": "csv \"desc,price\nred fish,100\nblue fish,200\"\n| render \n containerStyle={containerStyle backgroundColor=\"#ec77a8\" padding=\"4px\" opacity=\"0.7\"}", + "id": "element-223fe2b3-ffb4-4070-ae61-3e06b8052abb", + "position": { + "angle": 0, + "height": 132, + "left": 25, + "top": 390, + "width": 207 + } + }, + { + "expression": "filters\n| timelion query=\".es(index=logstash*,q=extension:jpg)\" interval=\"1M\" from=\"2017-01-01\" to=\"2017-12-31\"\n| table perPage=200\n| render containerStyle={containerStyle backgroundColor=\"#fd986f\" opacity=\"0.7\"}", + "id": "element-3c905696-8258-4e9c-ab58-89018681f79f", + "position": { + "angle": 0, + "height": 397, + "left": 263.5, + "top": 390, + "width": 533 + } + } + ], + "id": "page-c38cd459-10fe-45f9-847b-2cbd7ec74319", + "style": { + "background": "#fff" + }, + "transition": {} + } + ], + "width": 840 + }, + "coreMigrationVersion": "7.15.0", + "id": "workpad-1705f884-6224-47de-ba49-ca224fe6ec31-conflict-new", + "migrationVersion": { + "canvas-workpad": "7.0.0" + }, + "references": [], + "type": "canvas-workpad", + "updated_at": "2018-11-19T19:36:28.511Z", + "version": "WzUsMl0=" +} + +{ + "attributes": { + "@created": "2018-11-19T19:17:12.646Z", + "@timestamp": "2018-11-19T19:36:28.499Z", + "assets": {}, + "colors": [ + "#37988d", + "#c19628", + "#b83c6f", + "#3f9939", + "#1785b0", + "#ca5f35", + "#45bdb0", + "#f2bc33", + "#e74b8b", + "#4fbf48", + "#1ea6dc", + "#fd7643", + "#72cec3", + "#f5cc5d", + "#ec77a8", + "#7acf74", + "#4cbce4", + "#fd986f", + "#a1ded7", + "#f8dd91", + "#f2a4c5", + "#a6dfa2", + "#86d2ed", + "#fdba9f", + "#000000", + "#444444", + "#777777", + "#BBBBBB", + "#FFFFFF", + "rgba(255,255,255,0)" + ], + "height": 920, + "isWriteable": true, + "name": "Conflict Match Workpad", + "page": 0, + "pages": [ + { + "elements": [ + ], + "id": "page-c38cd459-10fe-45f9-847b-2cbd7ec74319", + "style": { + "background": "#fff" + }, + "transition": {} + } + ], + "width": 840 + }, + "coreMigrationVersion": "7.15.0", + "id": "workpad-1705f884-6224-47de-ba49-ca224fe6ec31-conflict-old", + "migrationVersion": { + "canvas-workpad": "7.0.0" + }, + "references": [], + "type": "canvas-workpad", + "updated_at": "2018-11-19T19:36:28.511Z", + "version": "WzUsMl0=" +} diff --git a/x-pack/test/functional/services/compare_images.ts b/x-pack/test/functional/services/compare_images.ts index 9ad98dff3819c..53b5ab7e0242f 100644 --- a/x-pack/test/functional/services/compare_images.ts +++ b/x-pack/test/functional/services/compare_images.ts @@ -7,7 +7,6 @@ import path from 'path'; import { promises as fs } from 'fs'; -import { pdf as pdfToPng } from 'pdf-to-img'; import { comparePngs } from '../../../../test/functional/services/lib/compare_pngs'; import { FtrProviderContext } from '../ftr_provider_context'; @@ -73,76 +72,6 @@ export function CompareImagesProvider({ getService }: FtrProviderContext) { log ); - return diffTotal; - }, - async checkIfPdfsMatch( - actualPdfPath: string, - baselinePdfPath: string, - screenshotsDirectory = screenshotsDir - ) { - log.debug(`checkIfPdfsMatch: ${actualPdfPath} vs ${baselinePdfPath}`); - // Copy the pdfs into the screenshot session directory, as that's where the generated pngs will automatically be - // stored. - const sessionDirectoryPath = path.resolve(screenshotsDirectory, 'session'); - const failureDirectoryPath = path.resolve(screenshotsDirectory, 'failure'); - - await fs.mkdir(sessionDirectoryPath, { recursive: true }); - await fs.mkdir(failureDirectoryPath, { recursive: true }); - - const actualPdfFileName = path.basename(actualPdfPath, '.pdf'); - const baselinePdfFileName = path.basename(baselinePdfPath, '.pdf'); - - const baselineCopyPath = path.resolve( - sessionDirectoryPath, - `${baselinePdfFileName}_baseline.pdf` - ); - const actualCopyPath = path.resolve(sessionDirectoryPath, `${actualPdfFileName}_actual.pdf`); - - // Don't cause a test failure if the baseline snapshot doesn't exist - we don't have all OS's covered and we - // don't want to start causing failures for other devs working on OS's which are lacking snapshots. We have - // mac and linux covered which is better than nothing for now. - try { - log.debug(`writeFileSync: ${baselineCopyPath}`); - await fs.writeFile(baselineCopyPath, await fs.readFile(baselinePdfPath)); - } catch (error) { - log.error(`No baseline pdf found at ${baselinePdfPath}`); - return 0; - } - log.debug(`writeFileSync: ${actualCopyPath}`); - await fs.writeFile(actualCopyPath, await fs.readFile(actualPdfPath)); - - const actualPdf = await pdfToPng(actualCopyPath); - const baselinePdf = await pdfToPng(baselineCopyPath); - - log.debug(`Checking number of pages`); - - if (actualPdf.length !== baselinePdf.length) { - throw new Error( - `Expected ${baselinePdf.length} pages but got ${actualPdf.length} in PDFs expected: "${baselineCopyPath}" actual: "${actualCopyPath}".` - ); - } - - let diffTotal = 0; - let pageNum = 1; - - for await (const actualPage of actualPdf) { - for await (const baselinePage of baselinePdf) { - const diffPngPath = path.resolve( - failureDirectoryPath, - `${baselinePdfFileName}-${pageNum}.png` - ); - diffTotal += await comparePngs( - { path: path.resolve(screenshotsDirectory, '_actual.png'), buffer: actualPage }, - { path: path.resolve(screenshotsDirectory, '_baseline.png'), buffer: baselinePage }, - diffPngPath, - sessionDirectoryPath, - log - ); - ++pageNum; - break; - } - } - return diffTotal; }, }; diff --git a/x-pack/test/functional/services/ml/dashboard_embeddables.ts b/x-pack/test/functional/services/ml/dashboard_embeddables.ts index 5c55a16698cb6..1eb4e25a4edd5 100644 --- a/x-pack/test/functional/services/ml/dashboard_embeddables.ts +++ b/x-pack/test/functional/services/ml/dashboard_embeddables.ts @@ -10,13 +10,14 @@ import { FtrProviderContext } from '../../ftr_provider_context'; import { MlDashboardJobSelectionTable } from './dashboard_job_selection_table'; export function MachineLearningDashboardEmbeddablesProvider( - { getService }: FtrProviderContext, + { getService, getPageObjects }: FtrProviderContext, mlDashboardJobSelectionTable: MlDashboardJobSelectionTable ) { const retry = getService('retry'); const testSubjects = getService('testSubjects'); const find = getService('find'); const dashboardAddPanel = getService('dashboardAddPanel'); + const PageObjects = getPageObjects(['discover']); return { async assertAnomalyChartsEmbeddableInitializerExists() { @@ -112,5 +113,13 @@ export function MachineLearningDashboardEmbeddablesProvider( await mlDashboardJobSelectionTable.assertJobSelectionTableExists(); }); }, + + async selectDiscoverIndexPattern(indexPattern: string) { + await retry.tryForTime(2 * 1000, async () => { + await PageObjects.discover.selectIndexPattern(indexPattern); + const indexPatternTitle = await testSubjects.getVisibleText('indexPattern-switch-link'); + expect(indexPatternTitle).to.be(indexPattern); + }); + }, }; } diff --git a/x-pack/test/functional/services/ml/data_visualizer_index_based.ts b/x-pack/test/functional/services/ml/data_visualizer_index_based.ts index 6883946452629..82ec33452a5b9 100644 --- a/x-pack/test/functional/services/ml/data_visualizer_index_based.ts +++ b/x-pack/test/functional/services/ml/data_visualizer_index_based.ts @@ -16,6 +16,7 @@ export function MachineLearningDataVisualizerIndexBasedProvider({ const retry = getService('retry'); const PageObjects = getPageObjects(['discover']); const queryBar = getService('queryBar'); + const filterBar = getService('filterBar'); return { async assertTimeRangeSelectorSectionExists() { @@ -208,5 +209,27 @@ export function MachineLearningDataVisualizerIndexBasedProvider({ ); }); }, + + async assertFilterBarFilterContent(filter: { + key: string; + value: string; + enabled?: boolean; + pinned?: boolean; + negated?: boolean; + }) { + await retry.waitForWithTimeout( + `filter ${JSON.stringify(filter)} to exist`, + 2000, + async () => { + return await filterBar.hasFilter( + filter.key, + filter.value, + filter.enabled, + filter.pinned, + filter.negated + ); + } + ); + }, }; } diff --git a/x-pack/test/functional/services/ml/security_common.ts b/x-pack/test/functional/services/ml/security_common.ts index 925565143bda0..7af8312855357 100644 --- a/x-pack/test/functional/services/ml/security_common.ts +++ b/x-pack/test/functional/services/ml/security_common.ts @@ -144,7 +144,9 @@ export function MachineLearningSecurityCommonProvider({ getService }: FtrProvide // such as "View in Lens", "Add to Dashboard", and creating anomaly detection rules. These feature privileges are the minimal ones // necessary to satisfy all of those functional tests. feature: { - discover: ['read'], + // FIXME: We need permission to save search in Discover to test the data viz embeddable + // change permission back to read once tests are moved out of ML + discover: ['all'], visualize: ['read'], dashboard: ['all'], actions: ['all'], diff --git a/x-pack/test/functional/services/ml/test_resources.ts b/x-pack/test/functional/services/ml/test_resources.ts index 071db63125a55..affd317d22e81 100644 --- a/x-pack/test/functional/services/ml/test_resources.ts +++ b/x-pack/test/functional/services/ml/test_resources.ts @@ -509,5 +509,18 @@ export function MachineLearningTestResourcesProvider({ getService }: FtrProvider log.debug(` > found version '${packageVersion}'`); return packageVersion; }, + + async setAdvancedSettingProperty( + propertyName: string, + propertyValue: string | number | boolean + ) { + await kibanaServer.uiSettings.update({ + [propertyName]: propertyValue, + }); + }, + + async clearAdvancedSettingProperty(propertyName: string) { + await kibanaServer.uiSettings.unset(propertyName); + }, }; } diff --git a/x-pack/test/functional/services/ml/trained_models_table.ts b/x-pack/test/functional/services/ml/trained_models_table.ts index 11a97a4fed8fe..dc1749ae15ac6 100644 --- a/x-pack/test/functional/services/ml/trained_models_table.ts +++ b/x-pack/test/functional/services/ml/trained_models_table.ts @@ -146,8 +146,8 @@ export function TrainedModelsTableProvider({ getService }: FtrProviderContext) { // 'Created at' will be different on each run, // so we will just assert that the value is in the expected timestamp format. expect(modelRow.createdAt).to.match( - /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/, - `Expected trained model row created at time to have same format as '2019-12-05 12:28:34' (got '${modelRow.createdAt}')` + /^\w{3}\s\d+,\s\d{4}\s@\s\d{2}:\d{2}:\d{2}\.\d{3}$/, + `Expected trained model row created at time to have same format as 'Dec 5, 2019 @ 12:28:34.594' (got '${modelRow.createdAt}')` ); } diff --git a/x-pack/test/functional/services/observability/alerts/common.ts b/x-pack/test/functional/services/observability/alerts/common.ts index 74fbbb742fa0e..8a32b41e9b8e9 100644 --- a/x-pack/test/functional/services/observability/alerts/common.ts +++ b/x-pack/test/functional/services/observability/alerts/common.ts @@ -43,6 +43,15 @@ export function ObservabilityAlertsCommonProvider({ ); }; + const navigateWithoutFilter = async () => { + return await pageObjects.common.navigateToUrlWithBrowserHistory( + 'observability', + '/alerts', + `?`, + { ensureCurrentUrl: false } + ); + }; + const setKibanaTimeZoneToUTC = async () => { await kibanaServer.uiSettings.update({ 'dateFormat:tz': 'UTC', @@ -61,6 +70,10 @@ export function ObservabilityAlertsCommonProvider({ return await testSubjects.findAll('dataGridRowCell'); }; + const getExperimentalDisclaimer = async () => { + return testSubjects.existOrFail('o11y-experimental-disclaimer'); + }; + const getTableCellsInRows = async () => { const columnHeaders = await getTableColumnHeaders(); if (columnHeaders.length <= 0) { @@ -243,6 +256,8 @@ export function ObservabilityAlertsCommonProvider({ typeInQueryBar, openActionsMenuForRow, getTimeRange, + navigateWithoutFilter, + getExperimentalDisclaimer, getActionsButtonByIndex, }; } diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts index 51a70026339c9..51aae6f4d134c 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts @@ -104,7 +104,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await testSubjects.click('test.always-firing-SelectOption'); } - describe('create alert', function () { + // Failing: See https://github.com/elastic/kibana/issues/89397 + describe.skip('create alert', function () { before(async () => { await pageObjects.common.navigateToApp('triggersActions'); await testSubjects.click('rulesTab'); diff --git a/x-pack/test/observability_functional/apps/observability/alerts/alert_disclaimer.ts b/x-pack/test/observability_functional/apps/observability/alerts/alert_disclaimer.ts new file mode 100644 index 0000000000000..c687210286304 --- /dev/null +++ b/x-pack/test/observability_functional/apps/observability/alerts/alert_disclaimer.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; + +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export default ({ getService, getPageObject }: FtrProviderContext) => { + describe('Observability alert experimental disclaimer', function () { + this.tags('includeFirefox'); + + const observability = getService('observability'); + const esArchiver = getService('esArchiver'); + const testSubjects = getService('testSubjects'); + + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/observability/alerts'); + await esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs'); + + await observability.alerts.common.navigateWithoutFilter(); + }); + + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs'); + await esArchiver.unload('x-pack/test/functional/es_archives/observability/alerts'); + }); + + it('Shows experimental disclaimer', async () => { + await observability.alerts.common.getExperimentalDisclaimer(); + }); + + it('Dismiss experimental disclaimer', async () => { + await testSubjects.click('o11y-experimental-disclaimer-dismiss-btn'); + const o11yExperimentalDisclaimer = await testSubjects.exists('o11y-experimental-disclaimer'); + expect(o11yExperimentalDisclaimer).not.to.be(null); + }); + }); +}; diff --git a/x-pack/test/observability_functional/apps/observability/index.ts b/x-pack/test/observability_functional/apps/observability/index.ts index 341927352aa28..898c7afb9a726 100644 --- a/x-pack/test/observability_functional/apps/observability/index.ts +++ b/x-pack/test/observability_functional/apps/observability/index.ts @@ -13,6 +13,7 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./feature_controls')); loadTestFile(require.resolve('./exploratory_view')); loadTestFile(require.resolve('./alerts')); + loadTestFile(require.resolve('./alerts/alert_disclaimer')); loadTestFile(require.resolve('./alerts/workflow_status')); loadTestFile(require.resolve('./alerts/pagination')); loadTestFile(require.resolve('./alerts/add_to_case')); diff --git a/x-pack/test/plugin_functional/plugins/timelines_test/public/applications/timelines_test/index.tsx b/x-pack/test/plugin_functional/plugins/timelines_test/public/applications/timelines_test/index.tsx index 48a17dc985003..1c04ca83f18dc 100644 --- a/x-pack/test/plugin_functional/plugins/timelines_test/public/applications/timelines_test/index.tsx +++ b/x-pack/test/plugin_functional/plugins/timelines_test/public/applications/timelines_test/index.tsx @@ -66,6 +66,7 @@ const AppRoot = React.memo( timelinesPluginSetup.getTGrid && timelinesPluginSetup.getTGrid<'standalone'>({ appId: 'securitySolution', + casesOwner: 'securitySolutionUI', type: 'standalone', casePermissions: { read: true, diff --git a/yarn.lock b/yarn.lock index 805235f9e2ddd..2c86be8359023 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4129,21 +4129,6 @@ resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.5.0.tgz#f60b6a55a5d8e5ee908347d2ce4250b15103dc8e" integrity sha512-/PT1P6DNf7vjEEiPkVIRJkvibbqWtqnyGaBz3nfRdcxclNSnSdaLU5tfAgcD7I8Yt5i+L19s406YLl1koLnLbg== -"@mapbox/node-pre-gyp@^1.0.0": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz#2a0b32fcb416fb3f2250fd24cb2a81421a4f5950" - integrity sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA== - dependencies: - detect-libc "^1.0.3" - https-proxy-agent "^5.0.0" - make-dir "^3.1.0" - node-fetch "^2.6.1" - nopt "^5.0.0" - npmlog "^4.1.2" - rimraf "^3.0.2" - semver "^7.3.4" - tar "^6.1.0" - "@mapbox/point-geometry@0.1.0", "@mapbox/point-geometry@^0.1.0", "@mapbox/point-geometry@~0.1.0": version "0.1.0" resolved "https://registry.yarnpkg.com/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz#8a83f9335c7860effa2eeeca254332aa0aeed8f2" @@ -10185,15 +10170,6 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001097, caniuse-lite@^1.0.30001109, can resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001261.tgz#96d89813c076ea061209a4e040d8dcf0c66a1d01" integrity sha512-vM8D9Uvp7bHIN0fZ2KQ4wnmYFpJo/Etb4Vwsuc+ka0tfGDHvOPrFm6S/7CCNLSOkAUjenT2HnUPESdOIL91FaA== -canvas@2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.8.0.tgz#f99ca7f25e6e26686661ffa4fec1239bbef74461" - integrity sha512-gLTi17X8WY9Cf5GZ2Yns8T5lfBOcGgFehDFb+JQwDqdOoBOcECS9ZWMEAqMSVcMYwXD659J8NyzjRY/2aE+C2Q== - dependencies: - "@mapbox/node-pre-gyp" "^1.0.0" - nan "^2.14.0" - simple-get "^3.0.3" - capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -22399,19 +22375,6 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" -pdf-to-img@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pdf-to-img/-/pdf-to-img-1.1.1.tgz#1918738477c3cc95a6786877bb1e36de81909400" - integrity sha512-e+4BpKSDhU+BZt34yo2P5OAqO0CRRy8xSNGDP7HhpT2FMEo5H7mzNcXdymYKRcj7xIr0eK1gYFhyjpWwHGp46Q== - dependencies: - canvas "2.8.0" - pdfjs-dist "2.9.359" - -pdfjs-dist@2.9.359: - version "2.9.359" - resolved "https://registry.yarnpkg.com/pdfjs-dist/-/pdfjs-dist-2.9.359.tgz#e67bafebf20e50fc41f1a5c189155ad008ac4f81" - integrity sha512-P2nYtkacdlZaNNwrBLw1ZyMm0oE2yY/5S/GDCAmMJ7U4+ciL/D0mrlEC/o4HZZc/LNE3w8lEVzBEyVgEQlPVKQ== - pdfkit@>=0.8.1, pdfkit@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/pdfkit/-/pdfkit-0.11.0.tgz#9cdb2fc42bd2913587fe3ddf48cc5bbb3c36f7de" @@ -26978,6 +26941,15 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" @@ -26987,15 +26959,6 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - "string.prototype.matchall@^4.0.0 || ^3.0.1", string.prototype.matchall@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz#59370644e1db7e4c0c045277690cf7b01203c4da" @@ -27655,7 +27618,7 @@ tar@6.1.9: mkdirp "^1.0.3" yallist "^4.0.0" -tar@^6.0.2, tar@^6.1.0, tar@^6.1.11, tar@^6.1.2: +tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: version "6.1.11" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== @@ -30226,13 +30189,20 @@ which@^1.2.14, which@^1.2.9, which@^1.3.1: dependencies: isexe "^2.0.0" -wide-align@1.1.3, wide-align@^1.1.0: +wide-align@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== dependencies: string-width "^1.0.2 || 2" +wide-align@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + widest-line@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc"