diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 27532f0f377f9a..96670b5d5107b0 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -12,6 +12,7 @@ /src/plugins/advanced_settings/ @elastic/kibana-app /src/plugins/charts/ @elastic/kibana-app /src/plugins/discover/ @elastic/kibana-app +/src/plugins/lens_oss/ @elastic/kibana-app /src/plugins/management/ @elastic/kibana-app /src/plugins/kibana_legacy/ @elastic/kibana-app /src/plugins/timelion/ @elastic/kibana-app diff --git a/.i18nrc.json b/.i18nrc.json index 68e38d3976a68b..653c67b535bff7 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -59,6 +59,8 @@ "visTypeVislib": "src/plugins/vis_type_vislib", "visTypeXy": "src/plugins/vis_type_xy", "visualizations": "src/plugins/visualizations", + "lensOss": "src/plugins/lens_oss", + "mapsOss": "src/plugins/maps_oss", "visualize": "src/plugins/visualize", "apmOss": "src/plugins/apm_oss", "usageCollection": "src/plugins/usage_collection" diff --git a/.sass-lint.yml b/.sass-lint.yml index 9eed50602f5205..85599750b0cb8d 100644 --- a/.sass-lint.yml +++ b/.sass-lint.yml @@ -6,6 +6,7 @@ files: - 'src/plugins/vis_type_vislib/**/*.s+(a|c)ss' - 'src/plugins/vis_type_vega/**/*.s+(a|c)ss' - 'src/plugins/vis_type_xy/**/*.s+(a|c)ss' + - 'src/plugins/visualizations/public/wizard/**/*.s+(a|c)ss' - 'x-pack/plugins/canvas/**/*.s+(a|c)ss' - 'x-pack/plugins/triggers_actions_ui/**/*.s+(a|c)ss' - 'x-pack/plugins/lens/**/*.s+(a|c)ss' diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 9235fc1198b12a..3c62c1fbca9825 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -28,9 +28,7 @@ allowing users to configure their advanced settings, also known as uiSettings within the code. -|{kib-repo}blob/{branch}/src/plugins/apm_oss[apmOss] -|WARNING: Missing README. - +|{kib-repo}blob/{branch}/src/plugins/apm_oss/README.asciidoc[apmOss] |{kib-repo}blob/{branch}/src/plugins/bfetch/README.md[bfetch] |bfetch allows to batch HTTP requests and streams responses back. @@ -132,6 +130,11 @@ in Kibana, e.g. visualizations. It has the form of a flyout panel. |The legacyExport plugin adds support for the legacy saved objects export format. +|{kib-repo}blob/{branch}/src/plugins/lens_oss/README.md[lensOss] +|The lens_oss plugin registers the lens visualization on OSS. +It is registered as disabled. The x-pack plugin should unregister this. + + |{kib-repo}blob/{branch}/src/plugins/management/README.md[management] |This plugins contains the "Stack Management" page framework. It offers navigation and an API to link individual managment section into it. This plugin does not contain any individual @@ -142,6 +145,11 @@ management section itself. |Internal objects used by the Coordinate, Region, and Vega visualizations. +|{kib-repo}blob/{branch}/src/plugins/maps_oss/README.md[mapsOss] +|The maps_oss plugin registers the maps visualization on OSS. +It is registered as disabled. The x-pack plugin should unregister this. + + |{kib-repo}blob/{branch}/src/plugins/navigation/README.md[navigation] |The navigation plugins exports the TopNavMenu component. It also provides a stateful version of it on the start contract. 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 3afd5eaa6f1f7d..9da31bb16b56b6 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 @@ -9,6 +9,7 @@ ```typescript readonly links: { readonly dashboard: { + readonly guide: string; readonly drilldowns: string; readonly drilldownsTriggerPicker: string; readonly urlDrilldownTemplateSyntax: 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 5249381969b98d..01504aafe3bae9 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 dashboard: {
readonly drilldowns: string;
readonly drilldownsTriggerPicker: string;
readonly urlDrilldownTemplateSyntax: string;
readonly urlDrilldownVariables: string;
};
readonly filebeat: {
readonly base: string;
readonly installation: string;
readonly configuration: string;
readonly elasticsearchOutput: string;
readonly startup: string;
readonly exportedFields: string;
};
readonly auditbeat: {
readonly base: string;
};
readonly metricbeat: {
readonly base: string;
};
readonly heartbeat: {
readonly base: string;
};
readonly logstash: {
readonly base: string;
};
readonly functionbeat: {
readonly base: string;
};
readonly winlogbeat: {
readonly base: string;
};
readonly aggs: {
readonly date_histogram: string;
readonly date_range: 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 scriptedFields: {
readonly scriptFields: string;
readonly scriptAggs: string;
readonly painless: string;
readonly painlessApi: string;
readonly painlessSyntax: string;
readonly luceneExpressions: string;
};
readonly indexPatterns: {
readonly loadingData: string;
readonly introduction: string;
};
readonly addData: string;
readonly kibana: string;
readonly siem: {
readonly guide: string;
readonly gettingStarted: string;
};
readonly query: {
readonly eql: string;
readonly luceneQuerySyntax: string;
readonly queryDsl: string;
readonly kueryQuerySyntax: string;
};
readonly date: {
readonly dateMath: string;
};
readonly management: Record<string, string>;
readonly visualize: Record<string, string>;
} | | +| [links](./kibana-plugin-core-public.doclinksstart.links.md) | {
readonly dashboard: {
readonly guide: string;
readonly drilldowns: string;
readonly drilldownsTriggerPicker: string;
readonly urlDrilldownTemplateSyntax: string;
readonly urlDrilldownVariables: string;
};
readonly filebeat: {
readonly base: string;
readonly installation: string;
readonly configuration: string;
readonly elasticsearchOutput: string;
readonly startup: string;
readonly exportedFields: string;
};
readonly auditbeat: {
readonly base: string;
};
readonly metricbeat: {
readonly base: string;
};
readonly heartbeat: {
readonly base: string;
};
readonly logstash: {
readonly base: string;
};
readonly functionbeat: {
readonly base: string;
};
readonly winlogbeat: {
readonly base: string;
};
readonly aggs: {
readonly date_histogram: string;
readonly date_range: 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 scriptedFields: {
readonly scriptFields: string;
readonly scriptAggs: string;
readonly painless: string;
readonly painlessApi: string;
readonly painlessSyntax: string;
readonly luceneExpressions: string;
};
readonly indexPatterns: {
readonly loadingData: string;
readonly introduction: string;
};
readonly addData: string;
readonly kibana: string;
readonly siem: {
readonly guide: string;
readonly gettingStarted: string;
};
readonly query: {
readonly eql: string;
readonly luceneQuerySyntax: string;
readonly queryDsl: string;
readonly kueryQuerySyntax: string;
};
readonly date: {
readonly dateMath: string;
};
readonly management: Record<string, string>;
readonly visualize: Record<string, string>;
} | | diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.fatalerror.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.fatalerror.md new file mode 100644 index 00000000000000..e937fa8fd80e76 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.fatalerror.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [fatalError](./kibana-plugin-plugins-embeddable-public.embeddable.fatalerror.md) + +## Embeddable.fatalError property + +Signature: + +```typescript +fatalError?: Error; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.md index 295cc10b1bb193..b1f1bed7541c37 100644 --- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.md +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.md @@ -20,6 +20,7 @@ export declare abstract class EmbeddableError | | | [id](./kibana-plugin-plugins-embeddable-public.embeddable.id.md) | | string | | | [input](./kibana-plugin-plugins-embeddable-public.embeddable.input.md) | | TEmbeddableInput | | | [isContainer](./kibana-plugin-plugins-embeddable-public.embeddable.iscontainer.md) | | boolean | | @@ -43,6 +44,7 @@ export declare abstract class Embeddable + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [onFatalError](./kibana-plugin-plugins-embeddable-public.embeddable.onfatalerror.md) + +## Embeddable.onFatalError() method + +Signature: + +```typescript +protected onFatalError(e: Error): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| e | Error | | + +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.fatalerror.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.fatalerror.md new file mode 100644 index 00000000000000..4b764a6ede079e --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.fatalerror.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [fatalError](./kibana-plugin-plugins-embeddable-public.iembeddable.fatalerror.md) + +## IEmbeddable.fatalError property + +If this embeddable has encountered a fatal error, that error will be stored here + +Signature: + +```typescript +fatalError?: Error; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.md index b3b6f961e56d1c..f96477ed65a04f 100644 --- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.md +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.md @@ -15,6 +15,7 @@ export interface IEmbeddableobject | Extra abilities added to Embeddable by *_enhanced plugins. | +| [fatalError](./kibana-plugin-plugins-embeddable-public.iembeddable.fatalerror.md) | Error | If this embeddable has encountered a fatal error, that error will be stored here | | [id](./kibana-plugin-plugins-embeddable-public.iembeddable.id.md) | string | A unique identifier for this embeddable. Mainly only used by containers to map their Panel States to a child embeddable instance. | | [isContainer](./kibana-plugin-plugins-embeddable-public.iembeddable.iscontainer.md) | boolean | Is this embeddable an instance of a Container class, can it contain nested embeddables? | | [parent](./kibana-plugin-plugins-embeddable-public.iembeddable.parent.md) | IContainer | If this embeddable is nested inside a container, this will contain a reference to its parent. | diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrenderer.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrenderer.md index 32a7151578658c..8cc32ff698b386 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrenderer.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrenderer.md @@ -7,5 +7,5 @@ Signature: ```typescript -ReactExpressionRenderer: ({ className, dataAttrs, padding, renderError, expression, onEvent, reload$, debounce, ...expressionLoaderOptions }: ReactExpressionRendererProps) => JSX.Element +ReactExpressionRenderer: ({ className, dataAttrs, padding, renderError, expression, onEvent, onData$, reload$, debounce, ...expressionLoaderOptions }: ReactExpressionRendererProps) => JSX.Element ``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md index e4980ce04b9e27..92ea071b23dfce 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md @@ -18,6 +18,7 @@ export interface ReactExpressionRendererProps extends IExpressionLoaderParams | [dataAttrs](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.dataattrs.md) | string[] | | | [debounce](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.debounce.md) | number | | | [expression](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.expression.md) | string | ExpressionAstExpression | | +| [onData$](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.ondata_.md) | <TData, TInspectorAdapters>(data: TData, adapters?: TInspectorAdapters) => void | | | [onEvent](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.onevent.md) | (event: ExpressionRendererEvent) => void | | | [padding](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.padding.md) | 'xs' | 's' | 'm' | 'l' | 'xl' | | | [reload$](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.reload_.md) | Observable<unknown> | An observable which can be used to re-run the expression without destroying the component | diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.ondata_.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.ondata_.md new file mode 100644 index 00000000000000..05ddb0b13a5bee --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.ondata_.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ReactExpressionRendererProps](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md) > [onData$](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.ondata_.md) + +## ReactExpressionRendererProps.onData$ property + +Signature: + +```typescript +onData$?: (data: TData, adapters?: TInspectorAdapters) => void; +``` diff --git a/docs/management/images/management-index-patterns.png b/docs/management/images/management-index-patterns.png deleted file mode 100644 index 232d32893b96d3..00000000000000 Binary files a/docs/management/images/management-index-patterns.png and /dev/null differ diff --git a/docs/management/managing-fields.asciidoc b/docs/management/managing-fields.asciidoc index 3734655edd91b3..1b9d22699d359e 100644 --- a/docs/management/managing-fields.asciidoc +++ b/docs/management/managing-fields.asciidoc @@ -1,70 +1,29 @@ [[managing-fields]] -== Index patterns and fields +== Field management -The *Index patterns* UI helps you create and manage -the index patterns that retrieve your data from {es}. +Whenever possible, +{kib} uses the same field type for display as {es}. However, a few field types +{es} supports are not available in {kib}. Use field formatters to customize how your +fields are displayed in Kibana, regardless of how they are stored in {es}. -[role="screenshot"] -image::images/management-index-patterns.png[] - -[float] -=== Required permissions - -The `Index Pattern Management` {kib} privilege is required to access the *Index patterns* UI. - -To add the privilege, open the menu, then click *Stack Management > Roles*. - -[float] -=== Create an index pattern - -An index pattern is the glue that connects {kib} to your {es} data. Create an -index pattern whenever you load your own data into {kib}. To get started, -click *Create index pattern*, and then follow the guided steps. Refer to -<> for the types of index patterns -that you can create. - -[float] -=== Manage your index pattern - -To view the fields and associated data types in an index pattern, click its name in -the *Index patterns* overview. - -[role="screenshot"] -image::management/index-patterns/images/new-index-pattern.png["Index files and data types"] - -Use the icons to perform the following actions: +Kibana provides these field formatters: -* [[set-default-pattern]]*Set the default index pattern.* {kib} uses a badge to make users -aware of which index pattern is the default. The first pattern -you create is automatically designated as the default pattern. The default -index pattern is loaded when you open *Discover*. +* <> +* <> +* <> +* <> -* *Refresh the index fields list.* You can refresh the index fields list to -pick up any newly-added fields. Doing so also resets the {kib} popularity counters -for the fields. The popularity counters are used in *Discover* to sort fields in lists. +To format a field: -* [[delete-pattern]]*Delete the index pattern.* This action removes the pattern from the list of -Saved Objects in {kib}. You will not be able to recover field formatters, -scripted fields, source filters, and field popularity data associated with the index pattern. -Deleting an index pattern does -not remove any indices or data documents from {es}. +. Open the main menu, and click *Stack Management > Index Patterns*. +. Click the index pattern that contains the field you want to format. +. Find the field you want to format and click the edit icon (image:management/index-patterns/images/edit_icon.png[]). +. Select a format and fill in the details. + -WARNING: Deleting an index pattern breaks all visualizations, saved searches, and -other saved objects that reference the pattern. - -[float] -=== Edit a field - -To edit a field's properties, click the edit icon -image:management/index-patterns/images/edit_icon.png[] in the detail view. -You can set the field's format and popularity value. +[role="screenshot"] +image:management/index-patterns/images/edit-field-format.png["Edit field format"] -Kibana has field formatters for the following field types: -* <> -* <> -* <> -* <> [[field-formatters-string]] === String field formatters @@ -121,12 +80,8 @@ WARNING: Computing data on the fly with scripted fields can be very resource int {kib} performance. Keep in mind that there's no built-in validation of a scripted field. If your scripts are buggy, you'll get exceptions whenever you try to view the dynamically generated data. -When you define a scripted field in {kib}, you have a choice of scripting languages. In 5.0 and later, the default -options are {ref}/modules-scripting-expression.html[Lucene expressions] and {ref}/modules-scripting-painless.html[Painless]. -While you can use other scripting languages if you enable dynamic scripting for them in {es}, this is not recommended -because they cannot be sufficiently {ref}/modules-scripting-security.html[sandboxed]. - -WARNING: In 5.0 and later, Groovy, JavaScript, and Python scripting are deprecated and unsupported. +When you define a scripted field in {kib}, you have a choice of the {ref}/modules-scripting-expression.html[Lucene expressions] or the +{ref}/modules-scripting-painless.html[Painless] scripting language. You can reference any single value numeric field in your expressions, for example: diff --git a/docs/settings/apm-settings.asciidoc b/docs/settings/apm-settings.asciidoc index b32c340df4adfd..79fa9a642428af 100644 --- a/docs/settings/apm-settings.asciidoc +++ b/docs/settings/apm-settings.asciidoc @@ -43,6 +43,9 @@ Changing these settings may disable features of the APM App. | `xpack.apm.enabled` | Set to `false` to disable the APM app. Defaults to `true`. +| `xpack.apm.maxServiceEnvironments` + | Maximum number of unique service environments recognized by the UI. Defaults to `100`. + | `xpack.apm.serviceMapFingerprintBucketSize` | Maximum number of unique transaction combinations sampled for generating service map focused on a specific service. Defaults to `100`. diff --git a/docs/settings/security-settings.asciidoc b/docs/settings/security-settings.asciidoc index 6b01094f7248a0..12043ead28d555 100644 --- a/docs/settings/security-settings.asciidoc +++ b/docs/settings/security-settings.asciidoc @@ -92,8 +92,8 @@ The valid settings in the `xpack.security.authc.providers` namespace vary depend `..icon` {ess-icon} | Custom icon for the provider entry displayed on the Login Selector UI. -| `xpack.security.authc.providers.` -`..showInSelector` {ess-icon} +| `xpack.security.authc.providers..` +`.showInSelector` {ess-icon} | Flag that indicates if the provider should have an entry on the Login Selector UI. Setting this to `false` doesn't remove the provider from the authentication chain. 2+a| @@ -103,10 +103,31 @@ The valid settings in the `xpack.security.authc.providers` namespace vary depend You are unable to set this setting to `false` for `basic` and `token` authentication providers. ============ -| `xpack.security.authc.providers.` -`..accessAgreement.message` {ess-icon} +| `xpack.security.authc.providers..` +`.accessAgreement.message` {ess-icon} | Access agreement text in Markdown format. For more information, refer to <>. +| [[xpack-security-provider-session-idleTimeout]] `xpack.security.authc.providers..` +`.session.idleTimeout` {ess-icon} +| Ensures that user sessions will expire after a period of inactivity. Setting this to `0` will prevent sessions from expiring because of inactivity. By default, this setting is equal to <>. + +2+a| +[TIP] +============ +Use a string of `[ms\|s\|m\|h\|d\|w\|M\|Y]` (e.g. '20m', '24h', '7d', '1w'). +============ + +| [[xpack-security-provider-session-lifespan]] `xpack.security.authc.providers..` +`.session.lifespan` {ess-icon} +| Ensures that user sessions will expire after the defined time period. This behavior is also known as an "absolute timeout". If +this is set to `0`, user sessions could stay active indefinitely. By default, this setting is equal to <>. + +2+a| +[TIP] +============ +Use a string of `[ms\|s\|m\|h\|d\|w\|M\|Y]` (e.g. '20m', '24h', '7d', '1w'). +============ + |=== [float] @@ -210,32 +231,32 @@ You can configure the following settings in the `kibana.yml` file. |[[xpack-session-idleTimeout]] `xpack.security.session.idleTimeout` {ess-icon} | Ensures that user sessions will expire after a period of inactivity. This and <> are both -highly recommended. By default, this setting is not set. +highly recommended. You can also specify this setting for <>. If this is _not_ set or set to `0`, then sessions will never expire due to inactivity. By default, this setting is not set. 2+a| [TIP] ============ -The format is a string of `[ms\|s\|m\|h\|d\|w\|M\|Y]` (e.g. '20m', '24h', '7d', '1w'). +Use a string of `[ms\|s\|m\|h\|d\|w\|M\|Y]` (e.g. '20m', '24h', '7d', '1w'). ============ |[[xpack-session-lifespan]] `xpack.security.session.lifespan` {ess-icon} - | Ensures that user sessions will expire after the defined time period. This behavior also known as an "absolute timeout". If -this is _not_ set, user sessions could stay active indefinitely. This and <> are both highly -recommended. By default, this setting is not set. + | Ensures that user sessions will expire after the defined time period. This behavior is also known as an "absolute timeout". If +this is _not_ set or set to `0`, user sessions could stay active indefinitely. This and <> are both highly +recommended. You can also specify this setting for <>. By default, this setting is not set. 2+a| [TIP] ============ -The format is a string of `[ms\|s\|m\|h\|d\|w\|M\|Y]` (e.g. '20m', '24h', '7d', '1w'). +Use a string of `[ms\|s\|m\|h\|d\|w\|M\|Y]` (e.g. '20m', '24h', '7d', '1w'). ============ -| `xpack.security.session.cleanupInterval` +| `xpack.security.session.cleanupInterval` {ess-icon} | Sets the interval at which {kib} tries to remove expired and invalid sessions from the session index. By default, this value is 1 hour. The minimum value is 10 seconds. 2+a| [TIP] ============ -The format is a string of `[ms\|s\|m\|h\|d\|w\|M\|Y]` (e.g. '20m', '24h', '7d', '1w'). +Use a string of `[ms\|s\|m\|h\|d\|w\|M\|Y]` (e.g. '20m', '24h', '7d', '1w'). ============ |=== diff --git a/docs/user/alerting/alerting-getting-started.asciidoc b/docs/user/alerting/alerting-getting-started.asciidoc index f8656b87cbe040..2b22b49375676f 100644 --- a/docs/user/alerting/alerting-getting-started.asciidoc +++ b/docs/user/alerting/alerting-getting-started.asciidoc @@ -169,12 +169,15 @@ If you are using an *on-premises* Elastic Stack deployment with <> +* <> * <> * <> * <> -See <> for more information on configuring roles that provide access to these features. +See <> for more information on configuring roles that provide access to these features. +Also note that a user will need +read+ privileges for the *Actions and Connectors* feature to attach actions to an alert or to edit an alert that has an action attached to it. [float] [[alerting-spaces]] diff --git a/package.json b/package.json index 44a0c833eae278..ade567c840da77 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,7 @@ "**/minimist": "^1.2.5", "**/node-jose/node-forge": "^0.10.0", "**/request": "^2.88.2", + "**/trim": "0.0.3", "**/typescript": "4.0.2" }, "engines": { @@ -236,6 +237,7 @@ "markdown-it": "^10.0.0", "md5": "^2.1.0", "mime": "^2.4.4", + "mime-types": "^2.1.27", "mini-css-extract-plugin": "0.8.0", "minimatch": "^3.0.4", "moment": "^2.24.0", @@ -567,7 +569,7 @@ "@types/zen-observable": "^0.8.0", "@typescript-eslint/eslint-plugin": "^3.10.0", "@typescript-eslint/parser": "^3.10.0", - "@welldone-software/why-did-you-render": "^4.0.0", + "@welldone-software/why-did-you-render": "^5.0.0", "@yarnpkg/lockfile": "^1.1.0", "abab": "^1.0.4", "angular-aria": "^1.8.0", @@ -842,15 +844,13 @@ "vinyl-fs": "^3.0.3", "wait-on": "^5.0.1", "watchpack": "^1.6.0", - "webpack-cli": "^3.3.10", - "webpack-dev-server": "^3.8.2", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0", "webpack-merge": "^4.2.2", "write-pkg": "^4.0.0", "xml-crypto": "^2.0.0", "xmlbuilder": "13.0.2", "yargs": "^15.4.1", - "yeoman-generator": "1.1.1", - "yo": "2.0.6", "zlib": "^1.0.5" } -} \ No newline at end of file +} diff --git a/packages/kbn-config/src/deprecation/deprecation_factory.test.ts b/packages/kbn-config/src/deprecation/deprecation_factory.test.ts index 3910ee3235cafe..64b02f104a1f1f 100644 --- a/packages/kbn-config/src/deprecation/deprecation_factory.test.ts +++ b/packages/kbn-config/src/deprecation/deprecation_factory.test.ts @@ -18,7 +18,7 @@ */ import { ConfigDeprecationLogger } from './types'; -import { configDeprecationFactory } from './deprecation_factory'; +import { configDeprecationFactory, copyFromRoot } from './deprecation_factory'; describe('DeprecationFactory', () => { const { rename, unused, renameFromRoot, unusedFromRoot } = configDeprecationFactory; @@ -250,6 +250,89 @@ describe('DeprecationFactory', () => { }); }); + describe('copyFromRoot', () => { + it('copies a property to a different namespace', () => { + const rawConfig = { + originplugin: { + deprecated: 'toberenamed', + valid: 'valid', + }, + destinationplugin: { + property: 'value', + }, + }; + const processed = copyFromRoot('originplugin.deprecated', 'destinationplugin.renamed')( + rawConfig, + 'does-not-matter', + logger + ); + expect(processed).toEqual({ + originplugin: { + deprecated: 'toberenamed', + valid: 'valid', + }, + destinationplugin: { + renamed: 'toberenamed', + property: 'value', + }, + }); + expect(deprecationMessages.length).toEqual(0); + }); + + it('does not alter config if origin property is not present', () => { + const rawConfig = { + myplugin: { + new: 'new', + valid: 'valid', + }, + someOtherPlugin: { + property: 'value', + }, + }; + const processed = copyFromRoot('myplugin.deprecated', 'myplugin.new')( + rawConfig, + 'does-not-matter', + logger + ); + expect(processed).toEqual({ + myplugin: { + new: 'new', + valid: 'valid', + }, + someOtherPlugin: { + property: 'value', + }, + }); + expect(deprecationMessages.length).toEqual(0); + }); + + it('does not alter config if they both exist', () => { + const rawConfig = { + myplugin: { + deprecated: 'deprecated', + renamed: 'renamed', + }, + someOtherPlugin: { + property: 'value', + }, + }; + const processed = copyFromRoot('myplugin.deprecated', 'someOtherPlugin.property')( + rawConfig, + 'does-not-matter', + logger + ); + expect(processed).toEqual({ + myplugin: { + deprecated: 'deprecated', + renamed: 'renamed', + }, + someOtherPlugin: { + property: 'value', + }, + }); + }); + }); + describe('unused', () => { it('removes the unused property from the config and logs a warning is present', () => { const rawConfig = { diff --git a/packages/kbn-config/src/deprecation/deprecation_factory.ts b/packages/kbn-config/src/deprecation/deprecation_factory.ts index 0598347d2cffcc..70a55fedf05bea 100644 --- a/packages/kbn-config/src/deprecation/deprecation_factory.ts +++ b/packages/kbn-config/src/deprecation/deprecation_factory.ts @@ -56,6 +56,26 @@ const _rename = ( return config; }; +const _copy = ( + config: Record, + rootPath: string, + originKey: string, + destinationKey: string +) => { + const originPath = getPath(rootPath, originKey); + const originValue = get(config, originPath); + if (originValue === undefined) { + return config; + } + + const destinationPath = getPath(rootPath, destinationKey); + const destinationValue = get(config, destinationPath); + if (destinationValue === undefined) { + set(config, destinationPath, originValue); + } + return config; +}; + const _unused = ( config: Record, rootPath: string, @@ -80,6 +100,12 @@ const renameFromRoot = (oldKey: string, newKey: string, silent?: boolean): Confi log ) => _rename(config, '', log, oldKey, newKey, silent); +export const copyFromRoot = (originKey: string, destinationKey: string): ConfigDeprecation => ( + config, + rootPath, + log +) => _copy(config, '', originKey, destinationKey); + const unused = (unusedKey: string): ConfigDeprecation => (config, rootPath, log) => _unused(config, rootPath, log, unusedKey); diff --git a/packages/kbn-config/src/deprecation/index.ts b/packages/kbn-config/src/deprecation/index.ts index 504dbfeeb001a4..4609b7b1d62d0d 100644 --- a/packages/kbn-config/src/deprecation/index.ts +++ b/packages/kbn-config/src/deprecation/index.ts @@ -24,5 +24,5 @@ export { ConfigDeprecationFactory, ConfigDeprecationProvider, } from './types'; -export { configDeprecationFactory } from './deprecation_factory'; +export { configDeprecationFactory, copyFromRoot } from './deprecation_factory'; export { applyDeprecations } from './apply_deprecations'; diff --git a/packages/kbn-config/src/index.ts b/packages/kbn-config/src/index.ts index 68609c6d5c7c31..b834568e8b3ae7 100644 --- a/packages/kbn-config/src/index.ts +++ b/packages/kbn-config/src/index.ts @@ -25,6 +25,7 @@ export { ConfigDeprecationLogger, ConfigDeprecationProvider, ConfigDeprecationWithContext, + copyFromRoot, } from './deprecation'; export { RawConfigurationProvider, RawConfigService, getConfigFromFiles } from './raw'; diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index 11e977c74cf22f..701b7cab21600d 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -45,6 +45,7 @@ pageLoadAssetSize: kibanaReact: 161921 kibanaUtils: 198829 lens: 96624 + lensOss: 19341 licenseManagement: 41817 licensing: 39008 lists: 183665 @@ -53,6 +54,7 @@ pageLoadAssetSize: maps: 183610 mapsLegacy: 116817 mapsLegacyLicensing: 20214 + mapsOss: 19284 ml: 82187 monitoring: 50000 navigation: 37269 diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index a780ec96dd9564..b7d9803059aa89 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -94,7 +94,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _cli__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "run", function() { return _cli__WEBPACK_IMPORTED_MODULE_0__["run"]; }); -/* harmony import */ var _production__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(506); +/* harmony import */ var _production__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(505); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _production__WEBPACK_IMPORTED_MODULE_1__["buildProductionProjects"]; }); /* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(248); @@ -106,7 +106,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _utils_package_json__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(251); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "transformDependencies", function() { return _utils_package_json__WEBPACK_IMPORTED_MODULE_4__["transformDependencies"]; }); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(505); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(504); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getProjectPaths", function() { return _config__WEBPACK_IMPORTED_MODULE_5__["getProjectPaths"]; }); /* @@ -150,7 +150,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _kbn_dev_utils_tooling_log__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5); /* harmony import */ var _kbn_dev_utils_tooling_log__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_kbn_dev_utils_tooling_log__WEBPACK_IMPORTED_MODULE_3__); /* harmony import */ var _commands__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(128); -/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(499); +/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(498); /* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(246); /* * Licensed to Elasticsearch B.V. under one or more contributor @@ -8897,9 +8897,9 @@ exports.ToolingLogCollectingWriter = ToolingLogCollectingWriter; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "commands", function() { return commands; }); /* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(129); -/* harmony import */ var _clean__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(365); -/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(398); -/* harmony import */ var _watch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(399); +/* harmony import */ var _clean__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(366); +/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(397); +/* harmony import */ var _watch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(398); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -8942,10 +8942,10 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(246); /* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(247); /* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(248); -/* harmony import */ var _utils_project_checksums__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(357); -/* harmony import */ var _utils_bootstrap_cache_file__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(362); -/* harmony import */ var _utils_yarn_lock__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(359); -/* harmony import */ var _utils_validate_dependencies__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(363); +/* harmony import */ var _utils_project_checksums__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(358); +/* harmony import */ var _utils_bootstrap_cache_file__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(363); +/* harmony import */ var _utils_yarn_lock__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(360); +/* harmony import */ var _utils_validate_dependencies__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(364); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -32193,7 +32193,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(314); /* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(349); +/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(350); /* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__); /* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(246); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } @@ -32289,13 +32289,13 @@ const childProcess = __webpack_require__(315); const crossSpawn = __webpack_require__(316); const stripFinalNewline = __webpack_require__(329); const npmRunPath = __webpack_require__(330); -const onetime = __webpack_require__(331); -const makeError = __webpack_require__(333); -const normalizeStdio = __webpack_require__(338); -const {spawnedKill, spawnedCancel, setupTimeout, setExitHandler} = __webpack_require__(339); -const {handleInput, getSpawnedResult, makeAllStream, validateInputSync} = __webpack_require__(340); -const {mergePromise, getSpawnedPromise} = __webpack_require__(347); -const {joinCommand, parseCommand} = __webpack_require__(348); +const onetime = __webpack_require__(332); +const makeError = __webpack_require__(334); +const normalizeStdio = __webpack_require__(339); +const {spawnedKill, spawnedCancel, setupTimeout, setExitHandler} = __webpack_require__(340); +const {handleInput, getSpawnedResult, makeAllStream, validateInputSync} = __webpack_require__(341); +const {mergePromise, getSpawnedPromise} = __webpack_require__(348); +const {joinCommand, parseCommand} = __webpack_require__(349); const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100; @@ -33274,7 +33274,7 @@ module.exports = input => { "use strict"; const path = __webpack_require__(4); -const pathKey = __webpack_require__(323); +const pathKey = __webpack_require__(331); const npmRunPath = options => { options = { @@ -33327,7 +33327,30 @@ module.exports.env = options => { "use strict"; -const mimicFn = __webpack_require__(332); + +const pathKey = (options = {}) => { + const environment = options.env || process.env; + const platform = options.platform || process.platform; + + if (platform !== 'win32') { + return 'PATH'; + } + + return Object.keys(environment).find(key => key.toUpperCase() === 'PATH') || 'Path'; +}; + +module.exports = pathKey; +// TODO: Remove this for the next major release +module.exports.default = pathKey; + + +/***/ }), +/* 332 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const mimicFn = __webpack_require__(333); const calledFunctions = new WeakMap(); @@ -33379,7 +33402,7 @@ module.exports.callCount = fn => { /***/ }), -/* 332 */ +/* 333 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -33399,12 +33422,12 @@ module.exports.default = mimicFn; /***/ }), -/* 333 */ +/* 334 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const {signalsByName} = __webpack_require__(334); +const {signalsByName} = __webpack_require__(335); const getErrorPrefix = ({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}) => { if (timedOut) { @@ -33492,14 +33515,14 @@ module.exports = makeError; /***/ }), -/* 334 */ +/* 335 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports,"__esModule",{value:true});exports.signalsByNumber=exports.signalsByName=void 0;var _os=__webpack_require__(121); -var _signals=__webpack_require__(335); -var _realtime=__webpack_require__(337); +var _signals=__webpack_require__(336); +var _realtime=__webpack_require__(338); @@ -33569,14 +33592,14 @@ const signalsByNumber=getSignalsByNumber();exports.signalsByNumber=signalsByNumb //# sourceMappingURL=main.js.map /***/ }), -/* 335 */ +/* 336 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports,"__esModule",{value:true});exports.getSignals=void 0;var _os=__webpack_require__(121); -var _core=__webpack_require__(336); -var _realtime=__webpack_require__(337); +var _core=__webpack_require__(337); +var _realtime=__webpack_require__(338); @@ -33610,7 +33633,7 @@ return{name,number,description,supported,action,forced,standard}; //# sourceMappingURL=signals.js.map /***/ }), -/* 336 */ +/* 337 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -33889,7 +33912,7 @@ standard:"other"}];exports.SIGNALS=SIGNALS; //# sourceMappingURL=core.js.map /***/ }), -/* 337 */ +/* 338 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -33914,7 +33937,7 @@ const SIGRTMAX=64;exports.SIGRTMAX=SIGRTMAX; //# sourceMappingURL=realtime.js.map /***/ }), -/* 338 */ +/* 339 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -33973,7 +33996,7 @@ module.exports.node = opts => { /***/ }), -/* 339 */ +/* 340 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -34092,14 +34115,14 @@ module.exports = { /***/ }), -/* 340 */ +/* 341 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const isStream = __webpack_require__(341); -const getStream = __webpack_require__(342); -const mergeStream = __webpack_require__(346); +const isStream = __webpack_require__(342); +const getStream = __webpack_require__(343); +const mergeStream = __webpack_require__(347); // `input` option const handleInput = (spawned, input) => { @@ -34196,7 +34219,7 @@ module.exports = { /***/ }), -/* 341 */ +/* 342 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -34232,13 +34255,13 @@ module.exports = isStream; /***/ }), -/* 342 */ +/* 343 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pump = __webpack_require__(343); -const bufferStream = __webpack_require__(345); +const pump = __webpack_require__(344); +const bufferStream = __webpack_require__(346); class MaxBufferError extends Error { constructor() { @@ -34297,11 +34320,11 @@ module.exports.MaxBufferError = MaxBufferError; /***/ }), -/* 343 */ +/* 344 */ /***/ (function(module, exports, __webpack_require__) { var once = __webpack_require__(162) -var eos = __webpack_require__(344) +var eos = __webpack_require__(345) var fs = __webpack_require__(134) // we only need fs to get the ReadStream and WriteStream prototypes var noop = function () {} @@ -34385,7 +34408,7 @@ module.exports = pump /***/ }), -/* 344 */ +/* 345 */ /***/ (function(module, exports, __webpack_require__) { var once = __webpack_require__(162); @@ -34485,7 +34508,7 @@ module.exports = eos; /***/ }), -/* 345 */ +/* 346 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -34544,7 +34567,7 @@ module.exports = options => { /***/ }), -/* 346 */ +/* 347 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -34592,7 +34615,7 @@ module.exports = function (/*streams...*/) { /***/ }), -/* 347 */ +/* 348 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -34645,7 +34668,7 @@ module.exports = { /***/ }), -/* 348 */ +/* 349 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -34690,7 +34713,7 @@ module.exports = { /***/ }), -/* 349 */ +/* 350 */ /***/ (function(module, exports, __webpack_require__) { // Copyright IBM Corp. 2014,2018. All Rights Reserved. @@ -34698,12 +34721,12 @@ module.exports = { // This file is licensed under the Apache License 2.0. // License text available at https://opensource.org/licenses/Apache-2.0 -module.exports = __webpack_require__(350); -module.exports.cli = __webpack_require__(354); +module.exports = __webpack_require__(351); +module.exports.cli = __webpack_require__(355); /***/ }), -/* 350 */ +/* 351 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -34718,9 +34741,9 @@ var stream = __webpack_require__(138); var util = __webpack_require__(112); var fs = __webpack_require__(134); -var through = __webpack_require__(351); -var duplexer = __webpack_require__(352); -var StringDecoder = __webpack_require__(353).StringDecoder; +var through = __webpack_require__(352); +var duplexer = __webpack_require__(353); +var StringDecoder = __webpack_require__(354).StringDecoder; module.exports = Logger; @@ -34909,7 +34932,7 @@ function lineMerger(host) { /***/ }), -/* 351 */ +/* 352 */ /***/ (function(module, exports, __webpack_require__) { var Stream = __webpack_require__(138) @@ -35023,7 +35046,7 @@ function through (write, end, opts) { /***/ }), -/* 352 */ +/* 353 */ /***/ (function(module, exports, __webpack_require__) { var Stream = __webpack_require__(138) @@ -35116,13 +35139,13 @@ function duplex(writer, reader) { /***/ }), -/* 353 */ +/* 354 */ /***/ (function(module, exports) { module.exports = require("string_decoder"); /***/ }), -/* 354 */ +/* 355 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -35133,11 +35156,11 @@ module.exports = require("string_decoder"); -var minimist = __webpack_require__(355); +var minimist = __webpack_require__(356); var path = __webpack_require__(4); -var Logger = __webpack_require__(350); -var pkg = __webpack_require__(356); +var Logger = __webpack_require__(351); +var pkg = __webpack_require__(357); module.exports = cli; @@ -35191,7 +35214,7 @@ function usage($0, p) { /***/ }), -/* 355 */ +/* 356 */ /***/ (function(module, exports) { module.exports = function (args, opts) { @@ -35442,13 +35465,13 @@ function isNumber (x) { /***/ }), -/* 356 */ +/* 357 */ /***/ (function(module) { module.exports = JSON.parse("{\"name\":\"strong-log-transformer\",\"version\":\"2.1.0\",\"description\":\"Stream transformer that prefixes lines with timestamps and other things.\",\"author\":\"Ryan Graham \",\"license\":\"Apache-2.0\",\"repository\":{\"type\":\"git\",\"url\":\"git://github.com/strongloop/strong-log-transformer\"},\"keywords\":[\"logging\",\"streams\"],\"bugs\":{\"url\":\"https://github.com/strongloop/strong-log-transformer/issues\"},\"homepage\":\"https://github.com/strongloop/strong-log-transformer\",\"directories\":{\"test\":\"test\"},\"bin\":{\"sl-log-transformer\":\"bin/sl-log-transformer.js\"},\"main\":\"index.js\",\"scripts\":{\"test\":\"tap --100 test/test-*\"},\"dependencies\":{\"duplexer\":\"^0.1.1\",\"minimist\":\"^1.2.0\",\"through\":\"^2.3.4\"},\"devDependencies\":{\"tap\":\"^12.0.1\"},\"engines\":{\"node\":\">=4\"}}"); /***/ }), -/* 357 */ +/* 358 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -35456,13 +35479,13 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getAllChecksums", function() { return getAllChecksums; }); /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(134); /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(358); +/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(359); /* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(crypto__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(112); /* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(314); /* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _yarn_lock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(359); +/* harmony import */ var _yarn_lock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(360); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -35661,20 +35684,20 @@ async function getAllChecksums(kbn, log, yarnLock) { } /***/ }), -/* 358 */ +/* 359 */ /***/ (function(module, exports) { module.exports = require("crypto"); /***/ }), -/* 359 */ +/* 360 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readYarnLock", function() { return readYarnLock; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resolveDepsForProject", function() { return resolveDepsForProject; }); -/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(360); +/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(361); /* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(131); /* @@ -35787,7 +35810,7 @@ function resolveDepsForProject({ } /***/ }), -/* 360 */ +/* 361 */ /***/ (function(module, exports, __webpack_require__) { module.exports = @@ -37346,7 +37369,7 @@ module.exports = invariant; /* 9 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(358); +module.exports = __webpack_require__(359); /***/ }), /* 10 */, @@ -39670,7 +39693,7 @@ function onceStrict (fn) { /* 63 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(361); +module.exports = __webpack_require__(362); /***/ }), /* 64 */, @@ -46065,13 +46088,13 @@ module.exports = process && support(supportLevel); /******/ ]); /***/ }), -/* 361 */ +/* 362 */ /***/ (function(module, exports) { module.exports = require("buffer"); /***/ }), -/* 362 */ +/* 363 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -46168,13 +46191,13 @@ class BootstrapCacheFile { } /***/ }), -/* 363 */ +/* 364 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "validateDependencies", function() { return validateDependencies; }); -/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(360); +/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(361); /* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var dedent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2); /* harmony import */ var dedent__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(dedent__WEBPACK_IMPORTED_MODULE_1__); @@ -46185,7 +46208,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(131); /* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(246); /* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(251); -/* harmony import */ var _projects_tree__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(364); +/* harmony import */ var _projects_tree__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(365); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -46377,7 +46400,7 @@ function getDevOnlyProductionDepsTree(kbn, projectName) { } /***/ }), -/* 364 */ +/* 365 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -46530,7 +46553,7 @@ function addProjectToTree(tree, pathParts, project) { } /***/ }), -/* 365 */ +/* 366 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -46538,7 +46561,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CleanCommand", function() { return CleanCommand; }); /* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(143); /* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(366); +/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(367); /* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(ora__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); @@ -46638,20 +46661,20 @@ const CleanCommand = { }; /***/ }), -/* 366 */ +/* 367 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const readline = __webpack_require__(367); -const chalk = __webpack_require__(368); -const cliCursor = __webpack_require__(375); -const cliSpinners = __webpack_require__(379); -const logSymbols = __webpack_require__(381); -const stripAnsi = __webpack_require__(390); -const wcwidth = __webpack_require__(392); -const isInteractive = __webpack_require__(396); -const MuteStream = __webpack_require__(397); +const readline = __webpack_require__(368); +const chalk = __webpack_require__(369); +const cliCursor = __webpack_require__(376); +const cliSpinners = __webpack_require__(378); +const logSymbols = __webpack_require__(380); +const stripAnsi = __webpack_require__(389); +const wcwidth = __webpack_require__(391); +const isInteractive = __webpack_require__(395); +const MuteStream = __webpack_require__(396); const TEXT = Symbol('text'); const PREFIX_TEXT = Symbol('prefixText'); @@ -47004,23 +47027,23 @@ module.exports.promise = (action, options) => { /***/ }), -/* 367 */ +/* 368 */ /***/ (function(module, exports) { module.exports = require("readline"); /***/ }), -/* 368 */ +/* 369 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const ansiStyles = __webpack_require__(369); +const ansiStyles = __webpack_require__(370); const {stdout: stdoutColor, stderr: stderrColor} = __webpack_require__(120); const { stringReplaceAll, stringEncaseCRLFWithFirstIndex -} = __webpack_require__(373); +} = __webpack_require__(374); // `supportsColor.level` → `ansiStyles.color[name]` mapping const levelMapping = [ @@ -47221,7 +47244,7 @@ const chalkTag = (chalk, ...strings) => { } if (template === undefined) { - template = __webpack_require__(374); + template = __webpack_require__(375); } return template(chalk, parts.join('')); @@ -47250,7 +47273,7 @@ module.exports = chalk; /***/ }), -/* 369 */ +/* 370 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -47296,7 +47319,7 @@ const setLazyProperty = (object, property, get) => { let colorConvert; const makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => { if (colorConvert === undefined) { - colorConvert = __webpack_require__(370); + colorConvert = __webpack_require__(371); } const offset = isBackground ? 10 : 0; @@ -47421,11 +47444,11 @@ Object.defineProperty(module, 'exports', { /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(115)(module))) /***/ }), -/* 370 */ +/* 371 */ /***/ (function(module, exports, __webpack_require__) { -const conversions = __webpack_require__(371); -const route = __webpack_require__(372); +const conversions = __webpack_require__(372); +const route = __webpack_require__(373); const convert = {}; @@ -47508,7 +47531,7 @@ module.exports = convert; /***/ }), -/* 371 */ +/* 372 */ /***/ (function(module, exports, __webpack_require__) { /* MIT license */ @@ -48353,10 +48376,10 @@ convert.rgb.gray = function (rgb) { /***/ }), -/* 372 */ +/* 373 */ /***/ (function(module, exports, __webpack_require__) { -const conversions = __webpack_require__(371); +const conversions = __webpack_require__(372); /* This function routes a model to all other models. @@ -48456,7 +48479,7 @@ module.exports = function (fromModel) { /***/ }), -/* 373 */ +/* 374 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48502,7 +48525,7 @@ module.exports = { /***/ }), -/* 374 */ +/* 375 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48643,12 +48666,12 @@ module.exports = (chalk, temporary) => { /***/ }), -/* 375 */ +/* 376 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const restoreCursor = __webpack_require__(376); +const restoreCursor = __webpack_require__(377); let isHidden = false; @@ -48685,12 +48708,12 @@ exports.toggle = (force, writableStream) => { /***/ }), -/* 376 */ +/* 377 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const onetime = __webpack_require__(377); +const onetime = __webpack_require__(332); const signalExit = __webpack_require__(304); module.exports = onetime(() => { @@ -48700,63 +48723,6 @@ module.exports = onetime(() => { }); -/***/ }), -/* 377 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const mimicFn = __webpack_require__(378); - -const calledFunctions = new WeakMap(); - -const oneTime = (fn, options = {}) => { - if (typeof fn !== 'function') { - throw new TypeError('Expected a function'); - } - - let ret; - let isCalled = false; - let callCount = 0; - const functionName = fn.displayName || fn.name || ''; - - const onetime = function (...args) { - calledFunctions.set(onetime, ++callCount); - - if (isCalled) { - if (options.throw === true) { - throw new Error(`Function \`${functionName}\` can only be called once`); - } - - return ret; - } - - isCalled = true; - ret = fn.apply(this, args); - fn = null; - - return ret; - }; - - mimicFn(onetime, fn); - calledFunctions.set(onetime, callCount); - - return onetime; -}; - -module.exports = oneTime; -// TODO: Remove this for the next major release -module.exports.default = oneTime; - -module.exports.callCount = fn => { - if (!calledFunctions.has(fn)) { - throw new Error(`The given function \`${fn.name}\` is not wrapped by the \`onetime\` package`); - } - - return calledFunctions.get(fn); -}; - - /***/ }), /* 378 */ /***/ (function(module, exports, __webpack_require__) { @@ -48764,27 +48730,7 @@ module.exports.callCount = fn => { "use strict"; -const mimicFn = (to, from) => { - for (const prop of Reflect.ownKeys(from)) { - Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop)); - } - - return to; -}; - -module.exports = mimicFn; -// TODO: Remove this for the next major release -module.exports.default = mimicFn; - - -/***/ }), -/* 379 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -const spinners = Object.assign({}, __webpack_require__(380)); +const spinners = Object.assign({}, __webpack_require__(379)); const spinnersList = Object.keys(spinners); @@ -48802,18 +48748,18 @@ module.exports.default = spinners; /***/ }), -/* 380 */ +/* 379 */ /***/ (function(module) { module.exports = JSON.parse("{\"dots\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠹\",\"⠸\",\"⠼\",\"⠴\",\"⠦\",\"⠧\",\"⠇\",\"⠏\"]},\"dots2\":{\"interval\":80,\"frames\":[\"⣾\",\"⣽\",\"⣻\",\"⢿\",\"⡿\",\"⣟\",\"⣯\",\"⣷\"]},\"dots3\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠞\",\"⠖\",\"⠦\",\"⠴\",\"⠲\",\"⠳\",\"⠓\"]},\"dots4\":{\"interval\":80,\"frames\":[\"⠄\",\"⠆\",\"⠇\",\"⠋\",\"⠙\",\"⠸\",\"⠰\",\"⠠\",\"⠰\",\"⠸\",\"⠙\",\"⠋\",\"⠇\",\"⠆\"]},\"dots5\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\"]},\"dots6\":{\"interval\":80,\"frames\":[\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠴\",\"⠲\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠚\",\"⠙\",\"⠉\",\"⠁\"]},\"dots7\":{\"interval\":80,\"frames\":[\"⠈\",\"⠉\",\"⠋\",\"⠓\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠖\",\"⠦\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\"]},\"dots8\":{\"interval\":80,\"frames\":[\"⠁\",\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\",\"⠈\"]},\"dots9\":{\"interval\":80,\"frames\":[\"⢹\",\"⢺\",\"⢼\",\"⣸\",\"⣇\",\"⡧\",\"⡗\",\"⡏\"]},\"dots10\":{\"interval\":80,\"frames\":[\"⢄\",\"⢂\",\"⢁\",\"⡁\",\"⡈\",\"⡐\",\"⡠\"]},\"dots11\":{\"interval\":100,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⡀\",\"⢀\",\"⠠\",\"⠐\",\"⠈\"]},\"dots12\":{\"interval\":80,\"frames\":[\"⢀⠀\",\"⡀⠀\",\"⠄⠀\",\"⢂⠀\",\"⡂⠀\",\"⠅⠀\",\"⢃⠀\",\"⡃⠀\",\"⠍⠀\",\"⢋⠀\",\"⡋⠀\",\"⠍⠁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⢈⠩\",\"⡀⢙\",\"⠄⡙\",\"⢂⠩\",\"⡂⢘\",\"⠅⡘\",\"⢃⠨\",\"⡃⢐\",\"⠍⡐\",\"⢋⠠\",\"⡋⢀\",\"⠍⡁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⠈⠩\",\"⠀⢙\",\"⠀⡙\",\"⠀⠩\",\"⠀⢘\",\"⠀⡘\",\"⠀⠨\",\"⠀⢐\",\"⠀⡐\",\"⠀⠠\",\"⠀⢀\",\"⠀⡀\"]},\"dots8Bit\":{\"interval\":80,\"frames\":[\"⠀\",\"⠁\",\"⠂\",\"⠃\",\"⠄\",\"⠅\",\"⠆\",\"⠇\",\"⡀\",\"⡁\",\"⡂\",\"⡃\",\"⡄\",\"⡅\",\"⡆\",\"⡇\",\"⠈\",\"⠉\",\"⠊\",\"⠋\",\"⠌\",\"⠍\",\"⠎\",\"⠏\",\"⡈\",\"⡉\",\"⡊\",\"⡋\",\"⡌\",\"⡍\",\"⡎\",\"⡏\",\"⠐\",\"⠑\",\"⠒\",\"⠓\",\"⠔\",\"⠕\",\"⠖\",\"⠗\",\"⡐\",\"⡑\",\"⡒\",\"⡓\",\"⡔\",\"⡕\",\"⡖\",\"⡗\",\"⠘\",\"⠙\",\"⠚\",\"⠛\",\"⠜\",\"⠝\",\"⠞\",\"⠟\",\"⡘\",\"⡙\",\"⡚\",\"⡛\",\"⡜\",\"⡝\",\"⡞\",\"⡟\",\"⠠\",\"⠡\",\"⠢\",\"⠣\",\"⠤\",\"⠥\",\"⠦\",\"⠧\",\"⡠\",\"⡡\",\"⡢\",\"⡣\",\"⡤\",\"⡥\",\"⡦\",\"⡧\",\"⠨\",\"⠩\",\"⠪\",\"⠫\",\"⠬\",\"⠭\",\"⠮\",\"⠯\",\"⡨\",\"⡩\",\"⡪\",\"⡫\",\"⡬\",\"⡭\",\"⡮\",\"⡯\",\"⠰\",\"⠱\",\"⠲\",\"⠳\",\"⠴\",\"⠵\",\"⠶\",\"⠷\",\"⡰\",\"⡱\",\"⡲\",\"⡳\",\"⡴\",\"⡵\",\"⡶\",\"⡷\",\"⠸\",\"⠹\",\"⠺\",\"⠻\",\"⠼\",\"⠽\",\"⠾\",\"⠿\",\"⡸\",\"⡹\",\"⡺\",\"⡻\",\"⡼\",\"⡽\",\"⡾\",\"⡿\",\"⢀\",\"⢁\",\"⢂\",\"⢃\",\"⢄\",\"⢅\",\"⢆\",\"⢇\",\"⣀\",\"⣁\",\"⣂\",\"⣃\",\"⣄\",\"⣅\",\"⣆\",\"⣇\",\"⢈\",\"⢉\",\"⢊\",\"⢋\",\"⢌\",\"⢍\",\"⢎\",\"⢏\",\"⣈\",\"⣉\",\"⣊\",\"⣋\",\"⣌\",\"⣍\",\"⣎\",\"⣏\",\"⢐\",\"⢑\",\"⢒\",\"⢓\",\"⢔\",\"⢕\",\"⢖\",\"⢗\",\"⣐\",\"⣑\",\"⣒\",\"⣓\",\"⣔\",\"⣕\",\"⣖\",\"⣗\",\"⢘\",\"⢙\",\"⢚\",\"⢛\",\"⢜\",\"⢝\",\"⢞\",\"⢟\",\"⣘\",\"⣙\",\"⣚\",\"⣛\",\"⣜\",\"⣝\",\"⣞\",\"⣟\",\"⢠\",\"⢡\",\"⢢\",\"⢣\",\"⢤\",\"⢥\",\"⢦\",\"⢧\",\"⣠\",\"⣡\",\"⣢\",\"⣣\",\"⣤\",\"⣥\",\"⣦\",\"⣧\",\"⢨\",\"⢩\",\"⢪\",\"⢫\",\"⢬\",\"⢭\",\"⢮\",\"⢯\",\"⣨\",\"⣩\",\"⣪\",\"⣫\",\"⣬\",\"⣭\",\"⣮\",\"⣯\",\"⢰\",\"⢱\",\"⢲\",\"⢳\",\"⢴\",\"⢵\",\"⢶\",\"⢷\",\"⣰\",\"⣱\",\"⣲\",\"⣳\",\"⣴\",\"⣵\",\"⣶\",\"⣷\",\"⢸\",\"⢹\",\"⢺\",\"⢻\",\"⢼\",\"⢽\",\"⢾\",\"⢿\",\"⣸\",\"⣹\",\"⣺\",\"⣻\",\"⣼\",\"⣽\",\"⣾\",\"⣿\"]},\"line\":{\"interval\":130,\"frames\":[\"-\",\"\\\\\",\"|\",\"/\"]},\"line2\":{\"interval\":100,\"frames\":[\"⠂\",\"-\",\"–\",\"—\",\"–\",\"-\"]},\"pipe\":{\"interval\":100,\"frames\":[\"┤\",\"┘\",\"┴\",\"└\",\"├\",\"┌\",\"┬\",\"┐\"]},\"simpleDots\":{\"interval\":400,\"frames\":[\". \",\".. \",\"...\",\" \"]},\"simpleDotsScrolling\":{\"interval\":200,\"frames\":[\". \",\".. \",\"...\",\" ..\",\" .\",\" \"]},\"star\":{\"interval\":70,\"frames\":[\"✶\",\"✸\",\"✹\",\"✺\",\"✹\",\"✷\"]},\"star2\":{\"interval\":80,\"frames\":[\"+\",\"x\",\"*\"]},\"flip\":{\"interval\":70,\"frames\":[\"_\",\"_\",\"_\",\"-\",\"`\",\"`\",\"'\",\"´\",\"-\",\"_\",\"_\",\"_\"]},\"hamburger\":{\"interval\":100,\"frames\":[\"☱\",\"☲\",\"☴\"]},\"growVertical\":{\"interval\":120,\"frames\":[\"▁\",\"▃\",\"▄\",\"▅\",\"▆\",\"▇\",\"▆\",\"▅\",\"▄\",\"▃\"]},\"growHorizontal\":{\"interval\":120,\"frames\":[\"▏\",\"▎\",\"▍\",\"▌\",\"▋\",\"▊\",\"▉\",\"▊\",\"▋\",\"▌\",\"▍\",\"▎\"]},\"balloon\":{\"interval\":140,\"frames\":[\" \",\".\",\"o\",\"O\",\"@\",\"*\",\" \"]},\"balloon2\":{\"interval\":120,\"frames\":[\".\",\"o\",\"O\",\"°\",\"O\",\"o\",\".\"]},\"noise\":{\"interval\":100,\"frames\":[\"▓\",\"▒\",\"░\"]},\"bounce\":{\"interval\":120,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⠂\"]},\"boxBounce\":{\"interval\":120,\"frames\":[\"▖\",\"▘\",\"▝\",\"▗\"]},\"boxBounce2\":{\"interval\":100,\"frames\":[\"▌\",\"▀\",\"▐\",\"▄\"]},\"triangle\":{\"interval\":50,\"frames\":[\"◢\",\"◣\",\"◤\",\"◥\"]},\"arc\":{\"interval\":100,\"frames\":[\"◜\",\"◠\",\"◝\",\"◞\",\"◡\",\"◟\"]},\"circle\":{\"interval\":120,\"frames\":[\"◡\",\"⊙\",\"◠\"]},\"squareCorners\":{\"interval\":180,\"frames\":[\"◰\",\"◳\",\"◲\",\"◱\"]},\"circleQuarters\":{\"interval\":120,\"frames\":[\"◴\",\"◷\",\"◶\",\"◵\"]},\"circleHalves\":{\"interval\":50,\"frames\":[\"◐\",\"◓\",\"◑\",\"◒\"]},\"squish\":{\"interval\":100,\"frames\":[\"╫\",\"╪\"]},\"toggle\":{\"interval\":250,\"frames\":[\"⊶\",\"⊷\"]},\"toggle2\":{\"interval\":80,\"frames\":[\"▫\",\"▪\"]},\"toggle3\":{\"interval\":120,\"frames\":[\"□\",\"■\"]},\"toggle4\":{\"interval\":100,\"frames\":[\"■\",\"□\",\"▪\",\"▫\"]},\"toggle5\":{\"interval\":100,\"frames\":[\"▮\",\"▯\"]},\"toggle6\":{\"interval\":300,\"frames\":[\"ဝ\",\"၀\"]},\"toggle7\":{\"interval\":80,\"frames\":[\"⦾\",\"⦿\"]},\"toggle8\":{\"interval\":100,\"frames\":[\"◍\",\"◌\"]},\"toggle9\":{\"interval\":100,\"frames\":[\"◉\",\"◎\"]},\"toggle10\":{\"interval\":100,\"frames\":[\"㊂\",\"㊀\",\"㊁\"]},\"toggle11\":{\"interval\":50,\"frames\":[\"⧇\",\"⧆\"]},\"toggle12\":{\"interval\":120,\"frames\":[\"☗\",\"☖\"]},\"toggle13\":{\"interval\":80,\"frames\":[\"=\",\"*\",\"-\"]},\"arrow\":{\"interval\":100,\"frames\":[\"←\",\"↖\",\"↑\",\"↗\",\"→\",\"↘\",\"↓\",\"↙\"]},\"arrow2\":{\"interval\":80,\"frames\":[\"⬆️ \",\"↗️ \",\"➡️ \",\"↘️ \",\"⬇️ \",\"↙️ \",\"⬅️ \",\"↖️ \"]},\"arrow3\":{\"interval\":120,\"frames\":[\"▹▹▹▹▹\",\"▸▹▹▹▹\",\"▹▸▹▹▹\",\"▹▹▸▹▹\",\"▹▹▹▸▹\",\"▹▹▹▹▸\"]},\"bouncingBar\":{\"interval\":80,\"frames\":[\"[ ]\",\"[= ]\",\"[== ]\",\"[=== ]\",\"[ ===]\",\"[ ==]\",\"[ =]\",\"[ ]\",\"[ =]\",\"[ ==]\",\"[ ===]\",\"[====]\",\"[=== ]\",\"[== ]\",\"[= ]\"]},\"bouncingBall\":{\"interval\":80,\"frames\":[\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ●)\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"(● )\"]},\"smiley\":{\"interval\":200,\"frames\":[\"😄 \",\"😝 \"]},\"monkey\":{\"interval\":300,\"frames\":[\"🙈 \",\"🙈 \",\"🙉 \",\"🙊 \"]},\"hearts\":{\"interval\":100,\"frames\":[\"💛 \",\"💙 \",\"💜 \",\"💚 \",\"❤️ \"]},\"clock\":{\"interval\":100,\"frames\":[\"🕛 \",\"🕐 \",\"🕑 \",\"🕒 \",\"🕓 \",\"🕔 \",\"🕕 \",\"🕖 \",\"🕗 \",\"🕘 \",\"🕙 \",\"🕚 \"]},\"earth\":{\"interval\":180,\"frames\":[\"🌍 \",\"🌎 \",\"🌏 \"]},\"material\":{\"interval\":17,\"frames\":[\"█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"███▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"████▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"██████▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"██████▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"███████▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"████████▁▁▁▁▁▁▁▁▁▁▁▁\",\"█████████▁▁▁▁▁▁▁▁▁▁▁\",\"█████████▁▁▁▁▁▁▁▁▁▁▁\",\"██████████▁▁▁▁▁▁▁▁▁▁\",\"███████████▁▁▁▁▁▁▁▁▁\",\"█████████████▁▁▁▁▁▁▁\",\"██████████████▁▁▁▁▁▁\",\"██████████████▁▁▁▁▁▁\",\"▁██████████████▁▁▁▁▁\",\"▁██████████████▁▁▁▁▁\",\"▁██████████████▁▁▁▁▁\",\"▁▁██████████████▁▁▁▁\",\"▁▁▁██████████████▁▁▁\",\"▁▁▁▁█████████████▁▁▁\",\"▁▁▁▁██████████████▁▁\",\"▁▁▁▁██████████████▁▁\",\"▁▁▁▁▁██████████████▁\",\"▁▁▁▁▁██████████████▁\",\"▁▁▁▁▁██████████████▁\",\"▁▁▁▁▁▁██████████████\",\"▁▁▁▁▁▁██████████████\",\"▁▁▁▁▁▁▁█████████████\",\"▁▁▁▁▁▁▁█████████████\",\"▁▁▁▁▁▁▁▁████████████\",\"▁▁▁▁▁▁▁▁████████████\",\"▁▁▁▁▁▁▁▁▁███████████\",\"▁▁▁▁▁▁▁▁▁███████████\",\"▁▁▁▁▁▁▁▁▁▁██████████\",\"▁▁▁▁▁▁▁▁▁▁██████████\",\"▁▁▁▁▁▁▁▁▁▁▁▁████████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁███████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁██████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████\",\"█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████\",\"██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███\",\"██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███\",\"███▁▁▁▁▁▁▁▁▁▁▁▁▁▁███\",\"████▁▁▁▁▁▁▁▁▁▁▁▁▁▁██\",\"█████▁▁▁▁▁▁▁▁▁▁▁▁▁▁█\",\"█████▁▁▁▁▁▁▁▁▁▁▁▁▁▁█\",\"██████▁▁▁▁▁▁▁▁▁▁▁▁▁█\",\"████████▁▁▁▁▁▁▁▁▁▁▁▁\",\"█████████▁▁▁▁▁▁▁▁▁▁▁\",\"█████████▁▁▁▁▁▁▁▁▁▁▁\",\"█████████▁▁▁▁▁▁▁▁▁▁▁\",\"█████████▁▁▁▁▁▁▁▁▁▁▁\",\"███████████▁▁▁▁▁▁▁▁▁\",\"████████████▁▁▁▁▁▁▁▁\",\"████████████▁▁▁▁▁▁▁▁\",\"██████████████▁▁▁▁▁▁\",\"██████████████▁▁▁▁▁▁\",\"▁██████████████▁▁▁▁▁\",\"▁██████████████▁▁▁▁▁\",\"▁▁▁█████████████▁▁▁▁\",\"▁▁▁▁▁████████████▁▁▁\",\"▁▁▁▁▁████████████▁▁▁\",\"▁▁▁▁▁▁███████████▁▁▁\",\"▁▁▁▁▁▁▁▁█████████▁▁▁\",\"▁▁▁▁▁▁▁▁█████████▁▁▁\",\"▁▁▁▁▁▁▁▁▁█████████▁▁\",\"▁▁▁▁▁▁▁▁▁█████████▁▁\",\"▁▁▁▁▁▁▁▁▁▁█████████▁\",\"▁▁▁▁▁▁▁▁▁▁▁████████▁\",\"▁▁▁▁▁▁▁▁▁▁▁████████▁\",\"▁▁▁▁▁▁▁▁▁▁▁▁███████▁\",\"▁▁▁▁▁▁▁▁▁▁▁▁███████▁\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁███████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁███████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁\"]},\"moon\":{\"interval\":80,\"frames\":[\"🌑 \",\"🌒 \",\"🌓 \",\"🌔 \",\"🌕 \",\"🌖 \",\"🌗 \",\"🌘 \"]},\"runner\":{\"interval\":140,\"frames\":[\"🚶 \",\"🏃 \"]},\"pong\":{\"interval\":80,\"frames\":[\"▐⠂ ▌\",\"▐⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂▌\",\"▐ ⠠▌\",\"▐ ⡀▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐⠠ ▌\"]},\"shark\":{\"interval\":120,\"frames\":[\"▐|\\\\____________▌\",\"▐_|\\\\___________▌\",\"▐__|\\\\__________▌\",\"▐___|\\\\_________▌\",\"▐____|\\\\________▌\",\"▐_____|\\\\_______▌\",\"▐______|\\\\______▌\",\"▐_______|\\\\_____▌\",\"▐________|\\\\____▌\",\"▐_________|\\\\___▌\",\"▐__________|\\\\__▌\",\"▐___________|\\\\_▌\",\"▐____________|\\\\▌\",\"▐____________/|▌\",\"▐___________/|_▌\",\"▐__________/|__▌\",\"▐_________/|___▌\",\"▐________/|____▌\",\"▐_______/|_____▌\",\"▐______/|______▌\",\"▐_____/|_______▌\",\"▐____/|________▌\",\"▐___/|_________▌\",\"▐__/|__________▌\",\"▐_/|___________▌\",\"▐/|____________▌\"]},\"dqpb\":{\"interval\":100,\"frames\":[\"d\",\"q\",\"p\",\"b\"]},\"weather\":{\"interval\":100,\"frames\":[\"☀️ \",\"☀️ \",\"☀️ \",\"🌤 \",\"⛅️ \",\"🌥 \",\"☁️ \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"⛈ \",\"🌨 \",\"🌧 \",\"🌨 \",\"☁️ \",\"🌥 \",\"⛅️ \",\"🌤 \",\"☀️ \",\"☀️ \"]},\"christmas\":{\"interval\":400,\"frames\":[\"🌲\",\"🎄\"]},\"grenade\":{\"interval\":80,\"frames\":[\"، \",\"′ \",\" ´ \",\" ‾ \",\" ⸌\",\" ⸊\",\" |\",\" ⁎\",\" ⁕\",\" ෴ \",\" ⁓\",\" \",\" \",\" \"]},\"point\":{\"interval\":125,\"frames\":[\"∙∙∙\",\"●∙∙\",\"∙●∙\",\"∙∙●\",\"∙∙∙\"]},\"layer\":{\"interval\":150,\"frames\":[\"-\",\"=\",\"≡\"]},\"betaWave\":{\"interval\":80,\"frames\":[\"ρββββββ\",\"βρβββββ\",\"ββρββββ\",\"βββρβββ\",\"ββββρββ\",\"βββββρβ\",\"ββββββρ\"]}}"); /***/ }), -/* 381 */ +/* 380 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const chalk = __webpack_require__(382); +const chalk = __webpack_require__(381); const isSupported = process.platform !== 'win32' || process.env.CI || process.env.TERM === 'xterm-256color'; @@ -48835,16 +48781,16 @@ module.exports = isSupported ? main : fallbacks; /***/ }), -/* 382 */ +/* 381 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const escapeStringRegexp = __webpack_require__(265); -const ansiStyles = __webpack_require__(383); -const stdoutColor = __webpack_require__(388).stdout; +const ansiStyles = __webpack_require__(382); +const stdoutColor = __webpack_require__(387).stdout; -const template = __webpack_require__(389); +const template = __webpack_require__(388); const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); @@ -49070,12 +49016,12 @@ module.exports.default = module.exports; // For TypeScript /***/ }), -/* 383 */ +/* 382 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(module) { -const colorConvert = __webpack_require__(384); +const colorConvert = __webpack_require__(383); const wrapAnsi16 = (fn, offset) => function () { const code = fn.apply(colorConvert, arguments); @@ -49243,11 +49189,11 @@ Object.defineProperty(module, 'exports', { /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(115)(module))) /***/ }), -/* 384 */ +/* 383 */ /***/ (function(module, exports, __webpack_require__) { -var conversions = __webpack_require__(385); -var route = __webpack_require__(387); +var conversions = __webpack_require__(384); +var route = __webpack_require__(386); var convert = {}; @@ -49327,11 +49273,11 @@ module.exports = convert; /***/ }), -/* 385 */ +/* 384 */ /***/ (function(module, exports, __webpack_require__) { /* MIT license */ -var cssKeywords = __webpack_require__(386); +var cssKeywords = __webpack_require__(385); // NOTE: conversions should only return primitive values (i.e. arrays, or // values that give correct `typeof` results). @@ -50201,7 +50147,7 @@ convert.rgb.gray = function (rgb) { /***/ }), -/* 386 */ +/* 385 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -50360,10 +50306,10 @@ module.exports = { /***/ }), -/* 387 */ +/* 386 */ /***/ (function(module, exports, __webpack_require__) { -var conversions = __webpack_require__(385); +var conversions = __webpack_require__(384); /* this function routes a model to all other models. @@ -50463,7 +50409,7 @@ module.exports = function (fromModel) { /***/ }), -/* 388 */ +/* 387 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -50601,7 +50547,7 @@ module.exports = { /***/ }), -/* 389 */ +/* 388 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -50736,18 +50682,18 @@ module.exports = (chalk, tmp) => { /***/ }), -/* 390 */ +/* 389 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const ansiRegex = __webpack_require__(391); +const ansiRegex = __webpack_require__(390); module.exports = string => typeof string === 'string' ? string.replace(ansiRegex(), '') : string; /***/ }), -/* 391 */ +/* 390 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -50764,14 +50710,14 @@ module.exports = ({onlyFirst = false} = {}) => { /***/ }), -/* 392 */ +/* 391 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var defaults = __webpack_require__(393) -var combining = __webpack_require__(395) +var defaults = __webpack_require__(392) +var combining = __webpack_require__(394) var DEFAULTS = { nul: 0, @@ -50870,10 +50816,10 @@ function bisearch(ucs) { /***/ }), -/* 393 */ +/* 392 */ /***/ (function(module, exports, __webpack_require__) { -var clone = __webpack_require__(394); +var clone = __webpack_require__(393); module.exports = function(options, defaults) { options = options || {}; @@ -50888,7 +50834,7 @@ module.exports = function(options, defaults) { }; /***/ }), -/* 394 */ +/* 393 */ /***/ (function(module, exports, __webpack_require__) { var clone = (function() { @@ -51060,7 +51006,7 @@ if ( true && module.exports) { /***/ }), -/* 395 */ +/* 394 */ /***/ (function(module, exports) { module.exports = [ @@ -51116,7 +51062,7 @@ module.exports = [ /***/ }), -/* 396 */ +/* 395 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -51132,7 +51078,7 @@ module.exports = ({stream = process.stdout} = {}) => { /***/ }), -/* 397 */ +/* 396 */ /***/ (function(module, exports, __webpack_require__) { var Stream = __webpack_require__(138) @@ -51283,7 +51229,7 @@ MuteStream.prototype.close = proxy('close') /***/ }), -/* 398 */ +/* 397 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51344,7 +51290,7 @@ const RunCommand = { }; /***/ }), -/* 399 */ +/* 398 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51354,7 +51300,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(246); /* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(247); /* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(248); -/* harmony import */ var _utils_watch__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(400); +/* harmony import */ var _utils_watch__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(399); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -51439,14 +51385,14 @@ const WatchCommand = { }; /***/ }), -/* 400 */ +/* 399 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "waitUntilWatchIsReady", function() { return waitUntilWatchIsReady; }); /* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8); -/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(401); +/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(400); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -51513,141 +51459,141 @@ function waitUntilWatchIsReady(stream, opts = {}) { } /***/ }), -/* 401 */ +/* 400 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(402); +/* harmony import */ var _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(401); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "audit", function() { return _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__["audit"]; }); -/* harmony import */ var _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(403); +/* harmony import */ var _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(402); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "auditTime", function() { return _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__["auditTime"]; }); -/* harmony import */ var _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(404); +/* harmony import */ var _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(403); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buffer", function() { return _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__["buffer"]; }); -/* harmony import */ var _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(405); +/* harmony import */ var _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(404); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferCount", function() { return _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__["bufferCount"]; }); -/* harmony import */ var _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(406); +/* harmony import */ var _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(405); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferTime", function() { return _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__["bufferTime"]; }); -/* harmony import */ var _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(407); +/* harmony import */ var _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(406); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferToggle", function() { return _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__["bufferToggle"]; }); -/* harmony import */ var _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(408); +/* harmony import */ var _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(407); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferWhen", function() { return _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__["bufferWhen"]; }); -/* harmony import */ var _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(409); +/* harmony import */ var _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(408); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "catchError", function() { return _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__["catchError"]; }); -/* harmony import */ var _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(410); +/* harmony import */ var _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(409); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineAll", function() { return _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__["combineAll"]; }); -/* harmony import */ var _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(411); +/* harmony import */ var _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(410); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineLatest", function() { return _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__["combineLatest"]; }); -/* harmony import */ var _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(412); +/* harmony import */ var _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(411); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__["concat"]; }); /* harmony import */ var _internal_operators_concatAll__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(80); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatAll", function() { return _internal_operators_concatAll__WEBPACK_IMPORTED_MODULE_11__["concatAll"]; }); -/* harmony import */ var _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(413); +/* harmony import */ var _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(412); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatMap", function() { return _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__["concatMap"]; }); -/* harmony import */ var _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(414); +/* harmony import */ var _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(413); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatMapTo", function() { return _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__["concatMapTo"]; }); -/* harmony import */ var _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(415); +/* harmony import */ var _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(414); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "count", function() { return _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__["count"]; }); -/* harmony import */ var _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(416); +/* harmony import */ var _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(415); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "debounce", function() { return _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__["debounce"]; }); -/* harmony import */ var _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(417); +/* harmony import */ var _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(416); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "debounceTime", function() { return _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__["debounceTime"]; }); -/* harmony import */ var _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(418); +/* harmony import */ var _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(417); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "defaultIfEmpty", function() { return _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__["defaultIfEmpty"]; }); -/* harmony import */ var _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(419); +/* harmony import */ var _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(418); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "delay", function() { return _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__["delay"]; }); -/* harmony import */ var _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(421); +/* harmony import */ var _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(420); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "delayWhen", function() { return _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__["delayWhen"]; }); -/* harmony import */ var _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(422); +/* harmony import */ var _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(421); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "dematerialize", function() { return _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__["dematerialize"]; }); -/* harmony import */ var _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(423); +/* harmony import */ var _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(422); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinct", function() { return _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__["distinct"]; }); -/* harmony import */ var _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(424); +/* harmony import */ var _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(423); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinctUntilChanged", function() { return _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__["distinctUntilChanged"]; }); -/* harmony import */ var _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(425); +/* harmony import */ var _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(424); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinctUntilKeyChanged", function() { return _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__["distinctUntilKeyChanged"]; }); -/* harmony import */ var _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(426); +/* harmony import */ var _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(425); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "elementAt", function() { return _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__["elementAt"]; }); -/* harmony import */ var _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(429); +/* harmony import */ var _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(428); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "endWith", function() { return _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__["endWith"]; }); -/* harmony import */ var _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(430); +/* harmony import */ var _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(429); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "every", function() { return _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__["every"]; }); -/* harmony import */ var _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(431); +/* harmony import */ var _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(430); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "exhaust", function() { return _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__["exhaust"]; }); -/* harmony import */ var _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(432); +/* harmony import */ var _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(431); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "exhaustMap", function() { return _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__["exhaustMap"]; }); -/* harmony import */ var _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(433); +/* harmony import */ var _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(432); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "expand", function() { return _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__["expand"]; }); /* harmony import */ var _internal_operators_filter__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(105); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "filter", function() { return _internal_operators_filter__WEBPACK_IMPORTED_MODULE_30__["filter"]; }); -/* harmony import */ var _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(434); +/* harmony import */ var _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(433); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "finalize", function() { return _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__["finalize"]; }); -/* harmony import */ var _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(435); +/* harmony import */ var _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(434); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "find", function() { return _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__["find"]; }); -/* harmony import */ var _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(436); +/* harmony import */ var _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(435); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "findIndex", function() { return _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__["findIndex"]; }); -/* harmony import */ var _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(437); +/* harmony import */ var _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(436); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "first", function() { return _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__["first"]; }); /* harmony import */ var _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(31); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "groupBy", function() { return _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_35__["groupBy"]; }); -/* harmony import */ var _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(438); +/* harmony import */ var _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(437); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ignoreElements", function() { return _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__["ignoreElements"]; }); -/* harmony import */ var _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(439); +/* harmony import */ var _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(438); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "isEmpty", function() { return _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__["isEmpty"]; }); -/* harmony import */ var _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(440); +/* harmony import */ var _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(439); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "last", function() { return _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__["last"]; }); /* harmony import */ var _internal_operators_map__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(66); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "map", function() { return _internal_operators_map__WEBPACK_IMPORTED_MODULE_39__["map"]; }); -/* harmony import */ var _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(442); +/* harmony import */ var _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(441); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mapTo", function() { return _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__["mapTo"]; }); -/* harmony import */ var _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(443); +/* harmony import */ var _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(442); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "materialize", function() { return _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__["materialize"]; }); -/* harmony import */ var _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(444); +/* harmony import */ var _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(443); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "max", function() { return _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__["max"]; }); -/* harmony import */ var _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(447); +/* harmony import */ var _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(446); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "merge", function() { return _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__["merge"]; }); /* harmony import */ var _internal_operators_mergeAll__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(81); @@ -51658,175 +51604,175 @@ __webpack_require__.r(__webpack_exports__); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "flatMap", function() { return _internal_operators_mergeMap__WEBPACK_IMPORTED_MODULE_45__["flatMap"]; }); -/* harmony import */ var _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(448); +/* harmony import */ var _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(447); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeMapTo", function() { return _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__["mergeMapTo"]; }); -/* harmony import */ var _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(449); +/* harmony import */ var _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(448); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeScan", function() { return _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__["mergeScan"]; }); -/* harmony import */ var _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(450); +/* harmony import */ var _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(449); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "min", function() { return _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__["min"]; }); -/* harmony import */ var _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(451); +/* harmony import */ var _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(450); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "multicast", function() { return _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__["multicast"]; }); /* harmony import */ var _internal_operators_observeOn__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(41); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "observeOn", function() { return _internal_operators_observeOn__WEBPACK_IMPORTED_MODULE_50__["observeOn"]; }); -/* harmony import */ var _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(452); +/* harmony import */ var _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(451); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__["onErrorResumeNext"]; }); -/* harmony import */ var _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(453); +/* harmony import */ var _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(452); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pairwise", function() { return _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__["pairwise"]; }); -/* harmony import */ var _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(454); +/* harmony import */ var _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(453); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__["partition"]; }); -/* harmony import */ var _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(455); +/* harmony import */ var _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(454); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pluck", function() { return _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__["pluck"]; }); -/* harmony import */ var _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(456); +/* harmony import */ var _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(455); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publish", function() { return _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__["publish"]; }); -/* harmony import */ var _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(457); +/* harmony import */ var _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(456); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishBehavior", function() { return _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__["publishBehavior"]; }); -/* harmony import */ var _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__ = __webpack_require__(458); +/* harmony import */ var _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__ = __webpack_require__(457); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishLast", function() { return _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__["publishLast"]; }); -/* harmony import */ var _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__ = __webpack_require__(459); +/* harmony import */ var _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__ = __webpack_require__(458); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishReplay", function() { return _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__["publishReplay"]; }); -/* harmony import */ var _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__ = __webpack_require__(460); +/* harmony import */ var _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__ = __webpack_require__(459); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "race", function() { return _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__["race"]; }); -/* harmony import */ var _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__ = __webpack_require__(445); +/* harmony import */ var _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__ = __webpack_require__(444); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "reduce", function() { return _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__["reduce"]; }); -/* harmony import */ var _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__ = __webpack_require__(461); +/* harmony import */ var _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__ = __webpack_require__(460); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "repeat", function() { return _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__["repeat"]; }); -/* harmony import */ var _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__ = __webpack_require__(462); +/* harmony import */ var _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__ = __webpack_require__(461); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "repeatWhen", function() { return _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__["repeatWhen"]; }); -/* harmony import */ var _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__ = __webpack_require__(463); +/* harmony import */ var _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__ = __webpack_require__(462); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "retry", function() { return _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__["retry"]; }); -/* harmony import */ var _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__ = __webpack_require__(464); +/* harmony import */ var _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__ = __webpack_require__(463); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "retryWhen", function() { return _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__["retryWhen"]; }); /* harmony import */ var _internal_operators_refCount__WEBPACK_IMPORTED_MODULE_65__ = __webpack_require__(30); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "refCount", function() { return _internal_operators_refCount__WEBPACK_IMPORTED_MODULE_65__["refCount"]; }); -/* harmony import */ var _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__ = __webpack_require__(465); +/* harmony import */ var _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__ = __webpack_require__(464); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sample", function() { return _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__["sample"]; }); -/* harmony import */ var _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__ = __webpack_require__(466); +/* harmony import */ var _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__ = __webpack_require__(465); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sampleTime", function() { return _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__["sampleTime"]; }); -/* harmony import */ var _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__ = __webpack_require__(446); +/* harmony import */ var _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__ = __webpack_require__(445); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "scan", function() { return _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__["scan"]; }); -/* harmony import */ var _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__ = __webpack_require__(467); +/* harmony import */ var _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__ = __webpack_require__(466); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sequenceEqual", function() { return _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__["sequenceEqual"]; }); -/* harmony import */ var _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__ = __webpack_require__(468); +/* harmony import */ var _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__ = __webpack_require__(467); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "share", function() { return _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__["share"]; }); -/* harmony import */ var _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__ = __webpack_require__(469); +/* harmony import */ var _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__ = __webpack_require__(468); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "shareReplay", function() { return _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__["shareReplay"]; }); -/* harmony import */ var _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__ = __webpack_require__(470); +/* harmony import */ var _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__ = __webpack_require__(469); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "single", function() { return _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__["single"]; }); -/* harmony import */ var _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__ = __webpack_require__(471); +/* harmony import */ var _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__ = __webpack_require__(470); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skip", function() { return _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__["skip"]; }); -/* harmony import */ var _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__ = __webpack_require__(472); +/* harmony import */ var _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__ = __webpack_require__(471); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipLast", function() { return _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__["skipLast"]; }); -/* harmony import */ var _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__ = __webpack_require__(473); +/* harmony import */ var _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__ = __webpack_require__(472); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipUntil", function() { return _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__["skipUntil"]; }); -/* harmony import */ var _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__ = __webpack_require__(474); +/* harmony import */ var _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__ = __webpack_require__(473); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipWhile", function() { return _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__["skipWhile"]; }); -/* harmony import */ var _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__ = __webpack_require__(475); +/* harmony import */ var _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__ = __webpack_require__(474); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "startWith", function() { return _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__["startWith"]; }); -/* harmony import */ var _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__ = __webpack_require__(476); +/* harmony import */ var _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__ = __webpack_require__(475); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "subscribeOn", function() { return _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__["subscribeOn"]; }); -/* harmony import */ var _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__ = __webpack_require__(478); +/* harmony import */ var _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__ = __webpack_require__(477); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchAll", function() { return _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__["switchAll"]; }); -/* harmony import */ var _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__ = __webpack_require__(479); +/* harmony import */ var _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__ = __webpack_require__(478); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchMap", function() { return _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__["switchMap"]; }); -/* harmony import */ var _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__ = __webpack_require__(480); +/* harmony import */ var _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__ = __webpack_require__(479); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchMapTo", function() { return _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__["switchMapTo"]; }); -/* harmony import */ var _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__ = __webpack_require__(428); +/* harmony import */ var _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__ = __webpack_require__(427); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "take", function() { return _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__["take"]; }); -/* harmony import */ var _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__ = __webpack_require__(441); +/* harmony import */ var _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__ = __webpack_require__(440); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeLast", function() { return _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__["takeLast"]; }); -/* harmony import */ var _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__ = __webpack_require__(481); +/* harmony import */ var _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__ = __webpack_require__(480); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeUntil", function() { return _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__["takeUntil"]; }); -/* harmony import */ var _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__ = __webpack_require__(482); +/* harmony import */ var _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__ = __webpack_require__(481); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeWhile", function() { return _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__["takeWhile"]; }); -/* harmony import */ var _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__ = __webpack_require__(483); +/* harmony import */ var _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__ = __webpack_require__(482); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "tap", function() { return _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__["tap"]; }); -/* harmony import */ var _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__ = __webpack_require__(484); +/* harmony import */ var _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__ = __webpack_require__(483); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throttle", function() { return _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__["throttle"]; }); -/* harmony import */ var _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__ = __webpack_require__(485); +/* harmony import */ var _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__ = __webpack_require__(484); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throttleTime", function() { return _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__["throttleTime"]; }); -/* harmony import */ var _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__ = __webpack_require__(427); +/* harmony import */ var _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__ = __webpack_require__(426); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throwIfEmpty", function() { return _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__["throwIfEmpty"]; }); -/* harmony import */ var _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__ = __webpack_require__(486); +/* harmony import */ var _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__ = __webpack_require__(485); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeInterval", function() { return _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__["timeInterval"]; }); -/* harmony import */ var _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__ = __webpack_require__(487); +/* harmony import */ var _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__ = __webpack_require__(486); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeout", function() { return _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__["timeout"]; }); -/* harmony import */ var _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__ = __webpack_require__(488); +/* harmony import */ var _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__ = __webpack_require__(487); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeoutWith", function() { return _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__["timeoutWith"]; }); -/* harmony import */ var _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__ = __webpack_require__(489); +/* harmony import */ var _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__ = __webpack_require__(488); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timestamp", function() { return _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__["timestamp"]; }); -/* harmony import */ var _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__ = __webpack_require__(490); +/* harmony import */ var _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__ = __webpack_require__(489); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__["toArray"]; }); -/* harmony import */ var _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__ = __webpack_require__(491); +/* harmony import */ var _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__ = __webpack_require__(490); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "window", function() { return _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__["window"]; }); -/* harmony import */ var _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__ = __webpack_require__(492); +/* harmony import */ var _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__ = __webpack_require__(491); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowCount", function() { return _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__["windowCount"]; }); -/* harmony import */ var _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__ = __webpack_require__(493); +/* harmony import */ var _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__ = __webpack_require__(492); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowTime", function() { return _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__["windowTime"]; }); -/* harmony import */ var _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__ = __webpack_require__(494); +/* harmony import */ var _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__ = __webpack_require__(493); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowToggle", function() { return _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__["windowToggle"]; }); -/* harmony import */ var _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__ = __webpack_require__(495); +/* harmony import */ var _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__ = __webpack_require__(494); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowWhen", function() { return _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__["windowWhen"]; }); -/* harmony import */ var _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__ = __webpack_require__(496); +/* harmony import */ var _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__ = __webpack_require__(495); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "withLatestFrom", function() { return _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__["withLatestFrom"]; }); -/* harmony import */ var _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__ = __webpack_require__(497); +/* harmony import */ var _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__ = __webpack_require__(496); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zip", function() { return _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__["zip"]; }); -/* harmony import */ var _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__ = __webpack_require__(498); +/* harmony import */ var _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__ = __webpack_require__(497); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zipAll", function() { return _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__["zipAll"]; }); /** PURE_IMPORTS_START PURE_IMPORTS_END */ @@ -51937,7 +51883,7 @@ __webpack_require__.r(__webpack_exports__); /***/ }), -/* 402 */ +/* 401 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52016,14 +51962,14 @@ var AuditSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 403 */ +/* 402 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "auditTime", function() { return auditTime; }); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); -/* harmony import */ var _audit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(402); +/* harmony import */ var _audit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(401); /* harmony import */ var _observable_timer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(108); /** PURE_IMPORTS_START _scheduler_async,_audit,_observable_timer PURE_IMPORTS_END */ @@ -52039,7 +51985,7 @@ function auditTime(duration, scheduler) { /***/ }), -/* 404 */ +/* 403 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52086,7 +52032,7 @@ var BufferSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 405 */ +/* 404 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52187,7 +52133,7 @@ var BufferSkipCountSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 406 */ +/* 405 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52348,7 +52294,7 @@ function dispatchBufferClose(arg) { /***/ }), -/* 407 */ +/* 406 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52467,7 +52413,7 @@ var BufferToggleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 408 */ +/* 407 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52560,7 +52506,7 @@ var BufferWhenSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 409 */ +/* 408 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52620,7 +52566,7 @@ var CatchSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 410 */ +/* 409 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52636,7 +52582,7 @@ function combineAll(project) { /***/ }), -/* 411 */ +/* 410 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52668,7 +52614,7 @@ function combineLatest() { /***/ }), -/* 412 */ +/* 411 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52688,7 +52634,7 @@ function concat() { /***/ }), -/* 413 */ +/* 412 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52704,13 +52650,13 @@ function concatMap(project, resultSelector) { /***/ }), -/* 414 */ +/* 413 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concatMapTo", function() { return concatMapTo; }); -/* harmony import */ var _concatMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(413); +/* harmony import */ var _concatMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(412); /** PURE_IMPORTS_START _concatMap PURE_IMPORTS_END */ function concatMapTo(innerObservable, resultSelector) { @@ -52720,7 +52666,7 @@ function concatMapTo(innerObservable, resultSelector) { /***/ }), -/* 415 */ +/* 414 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52785,7 +52731,7 @@ var CountSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 416 */ +/* 415 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52870,7 +52816,7 @@ var DebounceSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 417 */ +/* 416 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52946,7 +52892,7 @@ function dispatchNext(subscriber) { /***/ }), -/* 418 */ +/* 417 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52996,7 +52942,7 @@ var DefaultIfEmptySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 419 */ +/* 418 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53004,7 +52950,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "delay", function() { return delay; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(55); -/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(420); +/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(419); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(11); /* harmony import */ var _Notification__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(42); /** PURE_IMPORTS_START tslib,_scheduler_async,_util_isDate,_Subscriber,_Notification PURE_IMPORTS_END */ @@ -53103,7 +53049,7 @@ var DelayMessage = /*@__PURE__*/ (function () { /***/ }), -/* 420 */ +/* 419 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53117,7 +53063,7 @@ function isDate(value) { /***/ }), -/* 421 */ +/* 420 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53263,7 +53209,7 @@ var SubscriptionDelaySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 422 */ +/* 421 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53301,7 +53247,7 @@ var DeMaterializeSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 423 */ +/* 422 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53377,7 +53323,7 @@ var DistinctSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 424 */ +/* 423 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53448,13 +53394,13 @@ var DistinctUntilChangedSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 425 */ +/* 424 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "distinctUntilKeyChanged", function() { return distinctUntilKeyChanged; }); -/* harmony import */ var _distinctUntilChanged__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(424); +/* harmony import */ var _distinctUntilChanged__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(423); /** PURE_IMPORTS_START _distinctUntilChanged PURE_IMPORTS_END */ function distinctUntilKeyChanged(key, compare) { @@ -53464,7 +53410,7 @@ function distinctUntilKeyChanged(key, compare) { /***/ }), -/* 426 */ +/* 425 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53472,9 +53418,9 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "elementAt", function() { return elementAt; }); /* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(62); /* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(105); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(427); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(418); -/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(428); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(426); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(417); +/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(427); /** PURE_IMPORTS_START _util_ArgumentOutOfRangeError,_filter,_throwIfEmpty,_defaultIfEmpty,_take PURE_IMPORTS_END */ @@ -53496,7 +53442,7 @@ function elementAt(index, defaultValue) { /***/ }), -/* 427 */ +/* 426 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53562,7 +53508,7 @@ function defaultErrorFactory() { /***/ }), -/* 428 */ +/* 427 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53624,7 +53570,7 @@ var TakeSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 429 */ +/* 428 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53646,7 +53592,7 @@ function endWith() { /***/ }), -/* 430 */ +/* 429 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53708,7 +53654,7 @@ var EverySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 431 */ +/* 430 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53762,7 +53708,7 @@ var SwitchFirstSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 432 */ +/* 431 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53856,7 +53802,7 @@ var ExhaustMapSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 433 */ +/* 432 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53968,7 +53914,7 @@ var ExpandSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 434 */ +/* 433 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54006,7 +53952,7 @@ var FinallySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 435 */ +/* 434 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54078,13 +54024,13 @@ var FindValueSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 436 */ +/* 435 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findIndex", function() { return findIndex; }); -/* harmony import */ var _operators_find__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(435); +/* harmony import */ var _operators_find__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(434); /** PURE_IMPORTS_START _operators_find PURE_IMPORTS_END */ function findIndex(predicate, thisArg) { @@ -54094,7 +54040,7 @@ function findIndex(predicate, thisArg) { /***/ }), -/* 437 */ +/* 436 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54102,9 +54048,9 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "first", function() { return first; }); /* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63); /* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(105); -/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(428); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(418); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(427); +/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(427); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(417); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(426); /* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(25); /** PURE_IMPORTS_START _util_EmptyError,_filter,_take,_defaultIfEmpty,_throwIfEmpty,_util_identity PURE_IMPORTS_END */ @@ -54121,7 +54067,7 @@ function first(predicate, defaultValue) { /***/ }), -/* 438 */ +/* 437 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54158,7 +54104,7 @@ var IgnoreElementsSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 439 */ +/* 438 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54202,7 +54148,7 @@ var IsEmptySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 440 */ +/* 439 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54210,9 +54156,9 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "last", function() { return last; }); /* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63); /* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(105); -/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(441); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(427); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(418); +/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(440); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(426); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(417); /* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(25); /** PURE_IMPORTS_START _util_EmptyError,_filter,_takeLast,_throwIfEmpty,_defaultIfEmpty,_util_identity PURE_IMPORTS_END */ @@ -54229,7 +54175,7 @@ function last(predicate, defaultValue) { /***/ }), -/* 441 */ +/* 440 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54306,7 +54252,7 @@ var TakeLastSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 442 */ +/* 441 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54345,7 +54291,7 @@ var MapToSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 443 */ +/* 442 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54395,13 +54341,13 @@ var MaterializeSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 444 */ +/* 443 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "max", function() { return max; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(445); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(444); /** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ function max(comparer) { @@ -54414,15 +54360,15 @@ function max(comparer) { /***/ }), -/* 445 */ +/* 444 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reduce", function() { return reduce; }); -/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(446); -/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(441); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(418); +/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(445); +/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(440); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(417); /* harmony import */ var _util_pipe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(24); /** PURE_IMPORTS_START _scan,_takeLast,_defaultIfEmpty,_util_pipe PURE_IMPORTS_END */ @@ -54443,7 +54389,7 @@ function reduce(accumulator, seed) { /***/ }), -/* 446 */ +/* 445 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54525,7 +54471,7 @@ var ScanSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 447 */ +/* 446 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54545,7 +54491,7 @@ function merge() { /***/ }), -/* 448 */ +/* 447 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54570,7 +54516,7 @@ function mergeMapTo(innerObservable, resultSelector, concurrent) { /***/ }), -/* 449 */ +/* 448 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54679,13 +54625,13 @@ var MergeScanSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 450 */ +/* 449 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "min", function() { return min; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(445); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(444); /** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ function min(comparer) { @@ -54698,7 +54644,7 @@ function min(comparer) { /***/ }), -/* 451 */ +/* 450 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54747,7 +54693,7 @@ var MulticastOperator = /*@__PURE__*/ (function () { /***/ }), -/* 452 */ +/* 451 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54837,7 +54783,7 @@ var OnErrorResumeNextSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 453 */ +/* 452 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54885,7 +54831,7 @@ var PairwiseSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 454 */ +/* 453 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54908,7 +54854,7 @@ function partition(predicate, thisArg) { /***/ }), -/* 455 */ +/* 454 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54948,14 +54894,14 @@ function plucker(props, length) { /***/ }), -/* 456 */ +/* 455 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publish", function() { return publish; }); /* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(451); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(450); /** PURE_IMPORTS_START _Subject,_multicast PURE_IMPORTS_END */ @@ -54968,14 +54914,14 @@ function publish(selector) { /***/ }), -/* 457 */ +/* 456 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishBehavior", function() { return publishBehavior; }); /* harmony import */ var _BehaviorSubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(32); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(451); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(450); /** PURE_IMPORTS_START _BehaviorSubject,_multicast PURE_IMPORTS_END */ @@ -54986,14 +54932,14 @@ function publishBehavior(value) { /***/ }), -/* 458 */ +/* 457 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishLast", function() { return publishLast; }); /* harmony import */ var _AsyncSubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(451); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(450); /** PURE_IMPORTS_START _AsyncSubject,_multicast PURE_IMPORTS_END */ @@ -55004,14 +54950,14 @@ function publishLast() { /***/ }), -/* 459 */ +/* 458 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishReplay", function() { return publishReplay; }); /* harmony import */ var _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(451); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(450); /** PURE_IMPORTS_START _ReplaySubject,_multicast PURE_IMPORTS_END */ @@ -55027,7 +54973,7 @@ function publishReplay(bufferSize, windowTime, selectorOrScheduler, scheduler) { /***/ }), -/* 460 */ +/* 459 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55054,7 +55000,7 @@ function race() { /***/ }), -/* 461 */ +/* 460 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55119,7 +55065,7 @@ var RepeatSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 462 */ +/* 461 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55213,7 +55159,7 @@ var RepeatWhenSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 463 */ +/* 462 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55266,7 +55212,7 @@ var RetrySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 464 */ +/* 463 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55352,7 +55298,7 @@ var RetryWhenSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 465 */ +/* 464 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55407,7 +55353,7 @@ var SampleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 466 */ +/* 465 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55467,7 +55413,7 @@ function dispatchNotification(state) { /***/ }), -/* 467 */ +/* 466 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55590,13 +55536,13 @@ var SequenceEqualCompareToSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 468 */ +/* 467 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "share", function() { return share; }); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(451); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(450); /* harmony import */ var _refCount__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30); /* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(27); /** PURE_IMPORTS_START _multicast,_refCount,_Subject PURE_IMPORTS_END */ @@ -55613,7 +55559,7 @@ function share() { /***/ }), -/* 469 */ +/* 468 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55682,7 +55628,7 @@ function shareReplayOperator(_a) { /***/ }), -/* 470 */ +/* 469 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55762,7 +55708,7 @@ var SingleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 471 */ +/* 470 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55804,7 +55750,7 @@ var SkipSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 472 */ +/* 471 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55866,7 +55812,7 @@ var SkipLastSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 473 */ +/* 472 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55923,7 +55869,7 @@ var SkipUntilSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 474 */ +/* 473 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55979,7 +55925,7 @@ var SkipWhileSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 475 */ +/* 474 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56008,13 +55954,13 @@ function startWith() { /***/ }), -/* 476 */ +/* 475 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeOn", function() { return subscribeOn; }); -/* harmony import */ var _observable_SubscribeOnObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(477); +/* harmony import */ var _observable_SubscribeOnObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(476); /** PURE_IMPORTS_START _observable_SubscribeOnObservable PURE_IMPORTS_END */ function subscribeOn(scheduler, delay) { @@ -56039,7 +55985,7 @@ var SubscribeOnOperator = /*@__PURE__*/ (function () { /***/ }), -/* 477 */ +/* 476 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56103,13 +56049,13 @@ var SubscribeOnObservable = /*@__PURE__*/ (function (_super) { /***/ }), -/* 478 */ +/* 477 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchAll", function() { return switchAll; }); -/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(479); +/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(478); /* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(25); /** PURE_IMPORTS_START _switchMap,_util_identity PURE_IMPORTS_END */ @@ -56121,7 +56067,7 @@ function switchAll() { /***/ }), -/* 479 */ +/* 478 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56209,13 +56155,13 @@ var SwitchMapSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 480 */ +/* 479 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchMapTo", function() { return switchMapTo; }); -/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(479); +/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(478); /** PURE_IMPORTS_START _switchMap PURE_IMPORTS_END */ function switchMapTo(innerObservable, resultSelector) { @@ -56225,7 +56171,7 @@ function switchMapTo(innerObservable, resultSelector) { /***/ }), -/* 481 */ +/* 480 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56273,7 +56219,7 @@ var TakeUntilSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 482 */ +/* 481 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56341,7 +56287,7 @@ var TakeWhileSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 483 */ +/* 482 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56429,7 +56375,7 @@ var TapSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 484 */ +/* 483 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56531,7 +56477,7 @@ var ThrottleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 485 */ +/* 484 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56540,7 +56486,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(55); -/* harmony import */ var _throttle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(484); +/* harmony import */ var _throttle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(483); /** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async,_throttle PURE_IMPORTS_END */ @@ -56629,7 +56575,7 @@ function dispatchNext(arg) { /***/ }), -/* 486 */ +/* 485 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56637,7 +56583,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeInterval", function() { return timeInterval; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TimeInterval", function() { return TimeInterval; }); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); -/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(446); +/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(445); /* harmony import */ var _observable_defer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(91); /* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(66); /** PURE_IMPORTS_START _scheduler_async,_scan,_observable_defer,_map PURE_IMPORTS_END */ @@ -56673,7 +56619,7 @@ var TimeInterval = /*@__PURE__*/ (function () { /***/ }), -/* 487 */ +/* 486 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56681,7 +56627,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeout", function() { return timeout; }); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); /* harmony import */ var _util_TimeoutError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(64); -/* harmony import */ var _timeoutWith__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(488); +/* harmony import */ var _timeoutWith__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(487); /* harmony import */ var _observable_throwError__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(49); /** PURE_IMPORTS_START _scheduler_async,_util_TimeoutError,_timeoutWith,_observable_throwError PURE_IMPORTS_END */ @@ -56698,7 +56644,7 @@ function timeout(due, scheduler) { /***/ }), -/* 488 */ +/* 487 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56706,7 +56652,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeoutWith", function() { return timeoutWith; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(55); -/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(420); +/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(419); /* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(90); /** PURE_IMPORTS_START tslib,_scheduler_async,_util_isDate,_innerSubscribe PURE_IMPORTS_END */ @@ -56777,7 +56723,7 @@ var TimeoutWithSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 489 */ +/* 488 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56807,13 +56753,13 @@ var Timestamp = /*@__PURE__*/ (function () { /***/ }), -/* 490 */ +/* 489 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return toArray; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(445); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(444); /** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ function toArrayReducer(arr, item, index) { @@ -56830,7 +56776,7 @@ function toArray() { /***/ }), -/* 491 */ +/* 490 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56908,7 +56854,7 @@ var WindowSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 492 */ +/* 491 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56998,7 +56944,7 @@ var WindowCountSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 493 */ +/* 492 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57168,7 +57114,7 @@ function dispatchWindowClose(state) { /***/ }), -/* 494 */ +/* 493 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57311,7 +57257,7 @@ var WindowToggleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 495 */ +/* 494 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57408,7 +57354,7 @@ var WindowSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 496 */ +/* 495 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57503,7 +57449,7 @@ var WithLatestFromSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 497 */ +/* 496 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57525,7 +57471,7 @@ function zip() { /***/ }), -/* 498 */ +/* 497 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57541,7 +57487,7 @@ function zipAll(project) { /***/ }), -/* 499 */ +/* 498 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57550,8 +57496,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(249); /* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(246); /* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(248); -/* harmony import */ var _utils_projects_tree__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(364); -/* harmony import */ var _utils_kibana__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(500); +/* harmony import */ var _utils_projects_tree__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(365); +/* harmony import */ var _utils_kibana__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(499); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } @@ -57633,7 +57579,7 @@ function toArray(value) { } /***/ }), -/* 500 */ +/* 499 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57641,13 +57587,13 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Kibana", function() { return Kibana; }); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(501); +/* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(500); /* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(multimatch__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(239); /* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(is_path_inside__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _yarn_lock__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(359); +/* harmony import */ var _yarn_lock__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(360); /* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(248); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(505); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(504); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } @@ -57809,15 +57755,15 @@ class Kibana { } /***/ }), -/* 501 */ +/* 500 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const minimatch = __webpack_require__(150); -const arrayUnion = __webpack_require__(502); -const arrayDiffer = __webpack_require__(503); -const arrify = __webpack_require__(504); +const arrayUnion = __webpack_require__(501); +const arrayDiffer = __webpack_require__(502); +const arrify = __webpack_require__(503); module.exports = (list, patterns, options = {}) => { list = arrify(list); @@ -57841,7 +57787,7 @@ module.exports = (list, patterns, options = {}) => { /***/ }), -/* 502 */ +/* 501 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57853,7 +57799,7 @@ module.exports = (...arguments_) => { /***/ }), -/* 503 */ +/* 502 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57868,7 +57814,7 @@ module.exports = arrayDiffer; /***/ }), -/* 504 */ +/* 503 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57898,7 +57844,7 @@ module.exports = arrify; /***/ }), -/* 505 */ +/* 504 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57968,12 +57914,12 @@ function getProjectPaths({ } /***/ }), -/* 506 */ +/* 505 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var _build_production_projects__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(507); +/* harmony import */ var _build_production_projects__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(506); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _build_production_projects__WEBPACK_IMPORTED_MODULE_0__["buildProductionProjects"]; }); /* @@ -57997,19 +57943,19 @@ __webpack_require__.r(__webpack_exports__); /***/ }), -/* 507 */ +/* 506 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return buildProductionProjects; }); -/* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(508); +/* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(507); /* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(cpy__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); /* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(505); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(504); /* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(131); /* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(246); /* harmony import */ var _utils_package_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(251); @@ -58146,7 +58092,7 @@ async function copyToBuild(project, kibanaRoot, buildRoot) { } /***/ }), -/* 508 */ +/* 507 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58154,14 +58100,14 @@ async function copyToBuild(project, kibanaRoot, buildRoot) { const EventEmitter = __webpack_require__(156); const path = __webpack_require__(4); const os = __webpack_require__(121); -const pMap = __webpack_require__(509); -const arrify = __webpack_require__(510); -const globby = __webpack_require__(511); -const hasGlob = __webpack_require__(707); -const cpFile = __webpack_require__(709); -const junk = __webpack_require__(719); -const pFilter = __webpack_require__(720); -const CpyError = __webpack_require__(722); +const pMap = __webpack_require__(508); +const arrify = __webpack_require__(503); +const globby = __webpack_require__(509); +const hasGlob = __webpack_require__(705); +const cpFile = __webpack_require__(707); +const junk = __webpack_require__(717); +const pFilter = __webpack_require__(718); +const CpyError = __webpack_require__(720); const defaultOptions = { ignoreJunk: true @@ -58312,7 +58258,7 @@ module.exports = (source, destination, { /***/ }), -/* 509 */ +/* 508 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58400,47 +58346,17 @@ module.exports = async ( /***/ }), -/* 510 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -const arrify = value => { - if (value === null || value === undefined) { - return []; - } - - if (Array.isArray(value)) { - return value; - } - - if (typeof value === 'string') { - return [value]; - } - - if (typeof value[Symbol.iterator] === 'function') { - return [...value]; - } - - return [value]; -}; - -module.exports = arrify; - - -/***/ }), -/* 511 */ +/* 509 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(134); -const arrayUnion = __webpack_require__(512); +const arrayUnion = __webpack_require__(510); const glob = __webpack_require__(147); -const fastGlob = __webpack_require__(514); -const dirGlob = __webpack_require__(700); -const gitignore = __webpack_require__(703); +const fastGlob = __webpack_require__(512); +const dirGlob = __webpack_require__(698); +const gitignore = __webpack_require__(701); const DEFAULT_FILTER = () => false; @@ -58585,12 +58501,12 @@ module.exports.gitignore = gitignore; /***/ }), -/* 512 */ +/* 510 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var arrayUniq = __webpack_require__(513); +var arrayUniq = __webpack_require__(511); module.exports = function () { return arrayUniq([].concat.apply([], arguments)); @@ -58598,7 +58514,7 @@ module.exports = function () { /***/ }), -/* 513 */ +/* 511 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58667,10 +58583,10 @@ if ('Set' in global) { /***/ }), -/* 514 */ +/* 512 */ /***/ (function(module, exports, __webpack_require__) { -const pkg = __webpack_require__(515); +const pkg = __webpack_require__(513); module.exports = pkg.async; module.exports.default = pkg.async; @@ -58683,19 +58599,19 @@ module.exports.generateTasks = pkg.generateTasks; /***/ }), -/* 515 */ +/* 513 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var optionsManager = __webpack_require__(516); -var taskManager = __webpack_require__(517); -var reader_async_1 = __webpack_require__(671); -var reader_stream_1 = __webpack_require__(695); -var reader_sync_1 = __webpack_require__(696); -var arrayUtils = __webpack_require__(698); -var streamUtils = __webpack_require__(699); +var optionsManager = __webpack_require__(514); +var taskManager = __webpack_require__(515); +var reader_async_1 = __webpack_require__(669); +var reader_stream_1 = __webpack_require__(693); +var reader_sync_1 = __webpack_require__(694); +var arrayUtils = __webpack_require__(696); +var streamUtils = __webpack_require__(697); /** * Synchronous API. */ @@ -58761,7 +58677,7 @@ function isString(source) { /***/ }), -/* 516 */ +/* 514 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58799,13 +58715,13 @@ exports.prepare = prepare; /***/ }), -/* 517 */ +/* 515 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var patternUtils = __webpack_require__(518); +var patternUtils = __webpack_require__(516); /** * Generate tasks based on parent directory of each pattern. */ @@ -58896,16 +58812,16 @@ exports.convertPatternGroupToTask = convertPatternGroupToTask; /***/ }), -/* 518 */ +/* 516 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var path = __webpack_require__(4); -var globParent = __webpack_require__(519); +var globParent = __webpack_require__(517); var isGlob = __webpack_require__(172); -var micromatch = __webpack_require__(522); +var micromatch = __webpack_require__(520); var GLOBSTAR = '**'; /** * Return true for static pattern. @@ -59051,15 +58967,15 @@ exports.matchAny = matchAny; /***/ }), -/* 519 */ +/* 517 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var path = __webpack_require__(4); -var isglob = __webpack_require__(520); -var pathDirname = __webpack_require__(521); +var isglob = __webpack_require__(518); +var pathDirname = __webpack_require__(519); var isWin32 = __webpack_require__(121).platform() === 'win32'; module.exports = function globParent(str) { @@ -59082,7 +58998,7 @@ module.exports = function globParent(str) { /***/ }), -/* 520 */ +/* 518 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -59113,7 +59029,7 @@ module.exports = function isGlob(str) { /***/ }), -/* 521 */ +/* 519 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59263,7 +59179,7 @@ module.exports.win32 = win32; /***/ }), -/* 522 */ +/* 520 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59274,18 +59190,18 @@ module.exports.win32 = win32; */ var util = __webpack_require__(112); -var braces = __webpack_require__(523); -var toRegex = __webpack_require__(524); -var extend = __webpack_require__(637); +var braces = __webpack_require__(521); +var toRegex = __webpack_require__(522); +var extend = __webpack_require__(635); /** * Local dependencies */ -var compilers = __webpack_require__(639); -var parsers = __webpack_require__(666); -var cache = __webpack_require__(667); -var utils = __webpack_require__(668); +var compilers = __webpack_require__(637); +var parsers = __webpack_require__(664); +var cache = __webpack_require__(665); +var utils = __webpack_require__(666); var MAX_LENGTH = 1024 * 64; /** @@ -60147,7 +60063,7 @@ module.exports = micromatch; /***/ }), -/* 523 */ +/* 521 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60157,18 +60073,18 @@ module.exports = micromatch; * Module dependencies */ -var toRegex = __webpack_require__(524); -var unique = __webpack_require__(546); -var extend = __webpack_require__(547); +var toRegex = __webpack_require__(522); +var unique = __webpack_require__(544); +var extend = __webpack_require__(545); /** * Local dependencies */ -var compilers = __webpack_require__(549); -var parsers = __webpack_require__(562); -var Braces = __webpack_require__(566); -var utils = __webpack_require__(550); +var compilers = __webpack_require__(547); +var parsers = __webpack_require__(560); +var Braces = __webpack_require__(564); +var utils = __webpack_require__(548); var MAX_LENGTH = 1024 * 64; var cache = {}; @@ -60472,16 +60388,16 @@ module.exports = braces; /***/ }), -/* 524 */ +/* 522 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var safe = __webpack_require__(525); -var define = __webpack_require__(531); -var extend = __webpack_require__(539); -var not = __webpack_require__(543); +var safe = __webpack_require__(523); +var define = __webpack_require__(529); +var extend = __webpack_require__(537); +var not = __webpack_require__(541); var MAX_LENGTH = 1024 * 64; /** @@ -60634,10 +60550,10 @@ module.exports.makeRe = makeRe; /***/ }), -/* 525 */ +/* 523 */ /***/ (function(module, exports, __webpack_require__) { -var parse = __webpack_require__(526); +var parse = __webpack_require__(524); var types = parse.types; module.exports = function (re, opts) { @@ -60683,13 +60599,13 @@ function isRegExp (x) { /***/ }), -/* 526 */ +/* 524 */ /***/ (function(module, exports, __webpack_require__) { -var util = __webpack_require__(527); -var types = __webpack_require__(528); -var sets = __webpack_require__(529); -var positions = __webpack_require__(530); +var util = __webpack_require__(525); +var types = __webpack_require__(526); +var sets = __webpack_require__(527); +var positions = __webpack_require__(528); module.exports = function(regexpStr) { @@ -60971,11 +60887,11 @@ module.exports.types = types; /***/ }), -/* 527 */ +/* 525 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(528); -var sets = __webpack_require__(529); +var types = __webpack_require__(526); +var sets = __webpack_require__(527); // All of these are private and only used by randexp. @@ -61088,7 +61004,7 @@ exports.error = function(regexp, msg) { /***/ }), -/* 528 */ +/* 526 */ /***/ (function(module, exports) { module.exports = { @@ -61104,10 +61020,10 @@ module.exports = { /***/ }), -/* 529 */ +/* 527 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(528); +var types = __webpack_require__(526); var INTS = function() { return [{ type: types.RANGE , from: 48, to: 57 }]; @@ -61192,10 +61108,10 @@ exports.anyChar = function() { /***/ }), -/* 530 */ +/* 528 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(528); +var types = __webpack_require__(526); exports.wordBoundary = function() { return { type: types.POSITION, value: 'b' }; @@ -61215,7 +61131,7 @@ exports.end = function() { /***/ }), -/* 531 */ +/* 529 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61228,8 +61144,8 @@ exports.end = function() { -var isobject = __webpack_require__(532); -var isDescriptor = __webpack_require__(533); +var isobject = __webpack_require__(530); +var isDescriptor = __webpack_require__(531); var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) ? Reflect.defineProperty : Object.defineProperty; @@ -61260,7 +61176,7 @@ module.exports = function defineProperty(obj, key, val) { /***/ }), -/* 532 */ +/* 530 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61279,7 +61195,7 @@ module.exports = function isObject(val) { /***/ }), -/* 533 */ +/* 531 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61292,9 +61208,9 @@ module.exports = function isObject(val) { -var typeOf = __webpack_require__(534); -var isAccessor = __webpack_require__(535); -var isData = __webpack_require__(537); +var typeOf = __webpack_require__(532); +var isAccessor = __webpack_require__(533); +var isData = __webpack_require__(535); module.exports = function isDescriptor(obj, key) { if (typeOf(obj) !== 'object') { @@ -61308,7 +61224,7 @@ module.exports = function isDescriptor(obj, key) { /***/ }), -/* 534 */ +/* 532 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -61443,7 +61359,7 @@ function isBuffer(val) { /***/ }), -/* 535 */ +/* 533 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61456,7 +61372,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(536); +var typeOf = __webpack_require__(534); // accessor descriptor properties var accessor = { @@ -61519,7 +61435,7 @@ module.exports = isAccessorDescriptor; /***/ }), -/* 536 */ +/* 534 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -61654,7 +61570,7 @@ function isBuffer(val) { /***/ }), -/* 537 */ +/* 535 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61667,7 +61583,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(538); +var typeOf = __webpack_require__(536); module.exports = function isDataDescriptor(obj, prop) { // data descriptor properties @@ -61710,7 +61626,7 @@ module.exports = function isDataDescriptor(obj, prop) { /***/ }), -/* 538 */ +/* 536 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -61845,14 +61761,14 @@ function isBuffer(val) { /***/ }), -/* 539 */ +/* 537 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(540); -var assignSymbols = __webpack_require__(542); +var isExtendable = __webpack_require__(538); +var assignSymbols = __webpack_require__(540); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -61912,7 +61828,7 @@ function isEnum(obj, key) { /***/ }), -/* 540 */ +/* 538 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61925,7 +61841,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(541); +var isPlainObject = __webpack_require__(539); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -61933,7 +61849,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 541 */ +/* 539 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61946,7 +61862,7 @@ module.exports = function isExtendable(val) { -var isObject = __webpack_require__(532); +var isObject = __webpack_require__(530); function isObjectObject(o) { return isObject(o) === true @@ -61977,7 +61893,7 @@ module.exports = function isPlainObject(o) { /***/ }), -/* 542 */ +/* 540 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62024,14 +61940,14 @@ module.exports = function(receiver, objects) { /***/ }), -/* 543 */ +/* 541 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(544); -var safe = __webpack_require__(525); +var extend = __webpack_require__(542); +var safe = __webpack_require__(523); /** * The main export is a function that takes a `pattern` string and an `options` object. @@ -62103,14 +62019,14 @@ module.exports = toRegex; /***/ }), -/* 544 */ +/* 542 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(545); -var assignSymbols = __webpack_require__(542); +var isExtendable = __webpack_require__(543); +var assignSymbols = __webpack_require__(540); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -62170,7 +62086,7 @@ function isEnum(obj, key) { /***/ }), -/* 545 */ +/* 543 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62183,7 +62099,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(541); +var isPlainObject = __webpack_require__(539); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -62191,7 +62107,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 546 */ +/* 544 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62241,13 +62157,13 @@ module.exports.immutable = function uniqueImmutable(arr) { /***/ }), -/* 547 */ +/* 545 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(548); +var isObject = __webpack_require__(546); module.exports = function extend(o/*, objects*/) { if (!isObject(o)) { o = {}; } @@ -62281,7 +62197,7 @@ function hasOwn(obj, key) { /***/ }), -/* 548 */ +/* 546 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62301,13 +62217,13 @@ module.exports = function isExtendable(val) { /***/ }), -/* 549 */ +/* 547 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(550); +var utils = __webpack_require__(548); module.exports = function(braces, options) { braces.compiler @@ -62590,25 +62506,25 @@ function hasQueue(node) { /***/ }), -/* 550 */ +/* 548 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var splitString = __webpack_require__(551); +var splitString = __webpack_require__(549); var utils = module.exports; /** * Module dependencies */ -utils.extend = __webpack_require__(547); -utils.flatten = __webpack_require__(554); -utils.isObject = __webpack_require__(532); -utils.fillRange = __webpack_require__(555); -utils.repeat = __webpack_require__(561); -utils.unique = __webpack_require__(546); +utils.extend = __webpack_require__(545); +utils.flatten = __webpack_require__(552); +utils.isObject = __webpack_require__(530); +utils.fillRange = __webpack_require__(553); +utils.repeat = __webpack_require__(559); +utils.unique = __webpack_require__(544); utils.define = function(obj, key, val) { Object.defineProperty(obj, key, { @@ -62940,7 +62856,7 @@ utils.escapeRegex = function(str) { /***/ }), -/* 551 */ +/* 549 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62953,7 +62869,7 @@ utils.escapeRegex = function(str) { -var extend = __webpack_require__(552); +var extend = __webpack_require__(550); module.exports = function(str, options, fn) { if (typeof str !== 'string') { @@ -63118,14 +63034,14 @@ function keepEscaping(opts, str, idx) { /***/ }), -/* 552 */ +/* 550 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(553); -var assignSymbols = __webpack_require__(542); +var isExtendable = __webpack_require__(551); +var assignSymbols = __webpack_require__(540); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -63185,7 +63101,7 @@ function isEnum(obj, key) { /***/ }), -/* 553 */ +/* 551 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63198,7 +63114,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(541); +var isPlainObject = __webpack_require__(539); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -63206,7 +63122,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 554 */ +/* 552 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63235,7 +63151,7 @@ function flat(arr, res) { /***/ }), -/* 555 */ +/* 553 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63249,10 +63165,10 @@ function flat(arr, res) { var util = __webpack_require__(112); -var isNumber = __webpack_require__(556); -var extend = __webpack_require__(547); -var repeat = __webpack_require__(559); -var toRegex = __webpack_require__(560); +var isNumber = __webpack_require__(554); +var extend = __webpack_require__(545); +var repeat = __webpack_require__(557); +var toRegex = __webpack_require__(558); /** * Return a range of numbers or letters. @@ -63450,7 +63366,7 @@ module.exports = fillRange; /***/ }), -/* 556 */ +/* 554 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63463,7 +63379,7 @@ module.exports = fillRange; -var typeOf = __webpack_require__(557); +var typeOf = __webpack_require__(555); module.exports = function isNumber(num) { var type = typeOf(num); @@ -63479,10 +63395,10 @@ module.exports = function isNumber(num) { /***/ }), -/* 557 */ +/* 555 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(558); +var isBuffer = __webpack_require__(556); var toString = Object.prototype.toString; /** @@ -63601,7 +63517,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 558 */ +/* 556 */ /***/ (function(module, exports) { /*! @@ -63628,7 +63544,7 @@ function isSlowBuffer (obj) { /***/ }), -/* 559 */ +/* 557 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63705,7 +63621,7 @@ function repeat(str, num) { /***/ }), -/* 560 */ +/* 558 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63718,8 +63634,8 @@ function repeat(str, num) { -var repeat = __webpack_require__(559); -var isNumber = __webpack_require__(556); +var repeat = __webpack_require__(557); +var isNumber = __webpack_require__(554); var cache = {}; function toRegexRange(min, max, options) { @@ -64006,7 +63922,7 @@ module.exports = toRegexRange; /***/ }), -/* 561 */ +/* 559 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -64031,14 +63947,14 @@ module.exports = function repeat(ele, num) { /***/ }), -/* 562 */ +/* 560 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var Node = __webpack_require__(563); -var utils = __webpack_require__(550); +var Node = __webpack_require__(561); +var utils = __webpack_require__(548); /** * Braces parsers @@ -64398,15 +64314,15 @@ function concatNodes(pos, node, parent, options) { /***/ }), -/* 563 */ +/* 561 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(532); -var define = __webpack_require__(564); -var utils = __webpack_require__(565); +var isObject = __webpack_require__(530); +var define = __webpack_require__(562); +var utils = __webpack_require__(563); var ownNames; /** @@ -64897,7 +64813,7 @@ exports = module.exports = Node; /***/ }), -/* 564 */ +/* 562 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -64910,7 +64826,7 @@ exports = module.exports = Node; -var isDescriptor = __webpack_require__(533); +var isDescriptor = __webpack_require__(531); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -64935,13 +64851,13 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 565 */ +/* 563 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var typeOf = __webpack_require__(557); +var typeOf = __webpack_require__(555); var utils = module.exports; /** @@ -65961,17 +65877,17 @@ function assert(val, message) { /***/ }), -/* 566 */ +/* 564 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(547); -var Snapdragon = __webpack_require__(567); -var compilers = __webpack_require__(549); -var parsers = __webpack_require__(562); -var utils = __webpack_require__(550); +var extend = __webpack_require__(545); +var Snapdragon = __webpack_require__(565); +var compilers = __webpack_require__(547); +var parsers = __webpack_require__(560); +var utils = __webpack_require__(548); /** * Customize Snapdragon parser and renderer @@ -66072,17 +65988,17 @@ module.exports = Braces; /***/ }), -/* 567 */ +/* 565 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var Base = __webpack_require__(568); -var define = __webpack_require__(595); -var Compiler = __webpack_require__(605); -var Parser = __webpack_require__(634); -var utils = __webpack_require__(614); +var Base = __webpack_require__(566); +var define = __webpack_require__(593); +var Compiler = __webpack_require__(603); +var Parser = __webpack_require__(632); +var utils = __webpack_require__(612); var regexCache = {}; var cache = {}; @@ -66253,20 +66169,20 @@ module.exports.Parser = Parser; /***/ }), -/* 568 */ +/* 566 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(112); -var define = __webpack_require__(569); -var CacheBase = __webpack_require__(570); -var Emitter = __webpack_require__(571); -var isObject = __webpack_require__(532); -var merge = __webpack_require__(589); -var pascal = __webpack_require__(592); -var cu = __webpack_require__(593); +var define = __webpack_require__(567); +var CacheBase = __webpack_require__(568); +var Emitter = __webpack_require__(569); +var isObject = __webpack_require__(530); +var merge = __webpack_require__(587); +var pascal = __webpack_require__(590); +var cu = __webpack_require__(591); /** * Optionally define a custom `cache` namespace to use. @@ -66695,7 +66611,7 @@ module.exports.namespace = namespace; /***/ }), -/* 569 */ +/* 567 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -66708,7 +66624,7 @@ module.exports.namespace = namespace; -var isDescriptor = __webpack_require__(533); +var isDescriptor = __webpack_require__(531); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -66733,21 +66649,21 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 570 */ +/* 568 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(532); -var Emitter = __webpack_require__(571); -var visit = __webpack_require__(572); -var toPath = __webpack_require__(575); -var union = __webpack_require__(576); -var del = __webpack_require__(580); -var get = __webpack_require__(578); -var has = __webpack_require__(585); -var set = __webpack_require__(588); +var isObject = __webpack_require__(530); +var Emitter = __webpack_require__(569); +var visit = __webpack_require__(570); +var toPath = __webpack_require__(573); +var union = __webpack_require__(574); +var del = __webpack_require__(578); +var get = __webpack_require__(576); +var has = __webpack_require__(583); +var set = __webpack_require__(586); /** * Create a `Cache` constructor that when instantiated will @@ -67001,7 +66917,7 @@ module.exports.namespace = namespace; /***/ }), -/* 571 */ +/* 569 */ /***/ (function(module, exports, __webpack_require__) { @@ -67170,7 +67086,7 @@ Emitter.prototype.hasListeners = function(event){ /***/ }), -/* 572 */ +/* 570 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67183,8 +67099,8 @@ Emitter.prototype.hasListeners = function(event){ -var visit = __webpack_require__(573); -var mapVisit = __webpack_require__(574); +var visit = __webpack_require__(571); +var mapVisit = __webpack_require__(572); module.exports = function(collection, method, val) { var result; @@ -67207,7 +67123,7 @@ module.exports = function(collection, method, val) { /***/ }), -/* 573 */ +/* 571 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67220,7 +67136,7 @@ module.exports = function(collection, method, val) { -var isObject = __webpack_require__(532); +var isObject = __webpack_require__(530); module.exports = function visit(thisArg, method, target, val) { if (!isObject(thisArg) && typeof thisArg !== 'function') { @@ -67247,14 +67163,14 @@ module.exports = function visit(thisArg, method, target, val) { /***/ }), -/* 574 */ +/* 572 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(112); -var visit = __webpack_require__(573); +var visit = __webpack_require__(571); /** * Map `visit` over an array of objects. @@ -67291,7 +67207,7 @@ function isObject(val) { /***/ }), -/* 575 */ +/* 573 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67304,7 +67220,7 @@ function isObject(val) { -var typeOf = __webpack_require__(557); +var typeOf = __webpack_require__(555); module.exports = function toPath(args) { if (typeOf(args) !== 'arguments') { @@ -67331,16 +67247,16 @@ function filter(arr) { /***/ }), -/* 576 */ +/* 574 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(548); -var union = __webpack_require__(577); -var get = __webpack_require__(578); -var set = __webpack_require__(579); +var isObject = __webpack_require__(546); +var union = __webpack_require__(575); +var get = __webpack_require__(576); +var set = __webpack_require__(577); module.exports = function unionValue(obj, prop, value) { if (!isObject(obj)) { @@ -67368,7 +67284,7 @@ function arrayify(val) { /***/ }), -/* 577 */ +/* 575 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67404,7 +67320,7 @@ module.exports = function union(init) { /***/ }), -/* 578 */ +/* 576 */ /***/ (function(module, exports) { /*! @@ -67460,7 +67376,7 @@ function toString(val) { /***/ }), -/* 579 */ +/* 577 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67473,10 +67389,10 @@ function toString(val) { -var split = __webpack_require__(551); -var extend = __webpack_require__(547); -var isPlainObject = __webpack_require__(541); -var isObject = __webpack_require__(548); +var split = __webpack_require__(549); +var extend = __webpack_require__(545); +var isPlainObject = __webpack_require__(539); +var isObject = __webpack_require__(546); module.exports = function(obj, prop, val) { if (!isObject(obj)) { @@ -67522,7 +67438,7 @@ function isValidKey(key) { /***/ }), -/* 580 */ +/* 578 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67535,8 +67451,8 @@ function isValidKey(key) { -var isObject = __webpack_require__(532); -var has = __webpack_require__(581); +var isObject = __webpack_require__(530); +var has = __webpack_require__(579); module.exports = function unset(obj, prop) { if (!isObject(obj)) { @@ -67561,7 +67477,7 @@ module.exports = function unset(obj, prop) { /***/ }), -/* 581 */ +/* 579 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67574,9 +67490,9 @@ module.exports = function unset(obj, prop) { -var isObject = __webpack_require__(582); -var hasValues = __webpack_require__(584); -var get = __webpack_require__(578); +var isObject = __webpack_require__(580); +var hasValues = __webpack_require__(582); +var get = __webpack_require__(576); module.exports = function(obj, prop, noZero) { if (isObject(obj)) { @@ -67587,7 +67503,7 @@ module.exports = function(obj, prop, noZero) { /***/ }), -/* 582 */ +/* 580 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67600,7 +67516,7 @@ module.exports = function(obj, prop, noZero) { -var isArray = __webpack_require__(583); +var isArray = __webpack_require__(581); module.exports = function isObject(val) { return val != null && typeof val === 'object' && isArray(val) === false; @@ -67608,7 +67524,7 @@ module.exports = function isObject(val) { /***/ }), -/* 583 */ +/* 581 */ /***/ (function(module, exports) { var toString = {}.toString; @@ -67619,7 +67535,7 @@ module.exports = Array.isArray || function (arr) { /***/ }), -/* 584 */ +/* 582 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67662,7 +67578,7 @@ module.exports = function hasValue(o, noZero) { /***/ }), -/* 585 */ +/* 583 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67675,9 +67591,9 @@ module.exports = function hasValue(o, noZero) { -var isObject = __webpack_require__(532); -var hasValues = __webpack_require__(586); -var get = __webpack_require__(578); +var isObject = __webpack_require__(530); +var hasValues = __webpack_require__(584); +var get = __webpack_require__(576); module.exports = function(val, prop) { return hasValues(isObject(val) && prop ? get(val, prop) : val); @@ -67685,7 +67601,7 @@ module.exports = function(val, prop) { /***/ }), -/* 586 */ +/* 584 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67698,8 +67614,8 @@ module.exports = function(val, prop) { -var typeOf = __webpack_require__(587); -var isNumber = __webpack_require__(556); +var typeOf = __webpack_require__(585); +var isNumber = __webpack_require__(554); module.exports = function hasValue(val) { // is-number checks for NaN and other edge cases @@ -67752,10 +67668,10 @@ module.exports = function hasValue(val) { /***/ }), -/* 587 */ +/* 585 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(558); +var isBuffer = __webpack_require__(556); var toString = Object.prototype.toString; /** @@ -67877,7 +67793,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 588 */ +/* 586 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67890,10 +67806,10 @@ module.exports = function kindOf(val) { -var split = __webpack_require__(551); -var extend = __webpack_require__(547); -var isPlainObject = __webpack_require__(541); -var isObject = __webpack_require__(548); +var split = __webpack_require__(549); +var extend = __webpack_require__(545); +var isPlainObject = __webpack_require__(539); +var isObject = __webpack_require__(546); module.exports = function(obj, prop, val) { if (!isObject(obj)) { @@ -67939,14 +67855,14 @@ function isValidKey(key) { /***/ }), -/* 589 */ +/* 587 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(590); -var forIn = __webpack_require__(591); +var isExtendable = __webpack_require__(588); +var forIn = __webpack_require__(589); function mixinDeep(target, objects) { var len = arguments.length, i = 0; @@ -68010,7 +67926,7 @@ module.exports = mixinDeep; /***/ }), -/* 590 */ +/* 588 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68023,7 +67939,7 @@ module.exports = mixinDeep; -var isPlainObject = __webpack_require__(541); +var isPlainObject = __webpack_require__(539); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -68031,7 +67947,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 591 */ +/* 589 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68054,7 +67970,7 @@ module.exports = function forIn(obj, fn, thisArg) { /***/ }), -/* 592 */ +/* 590 */ /***/ (function(module, exports) { /*! @@ -68081,14 +67997,14 @@ module.exports = pascalcase; /***/ }), -/* 593 */ +/* 591 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(112); -var utils = __webpack_require__(594); +var utils = __webpack_require__(592); /** * Expose class utils @@ -68453,7 +68369,7 @@ cu.bubble = function(Parent, events) { /***/ }), -/* 594 */ +/* 592 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68467,10 +68383,10 @@ var utils = {}; * Lazily required module dependencies */ -utils.union = __webpack_require__(577); -utils.define = __webpack_require__(595); -utils.isObj = __webpack_require__(532); -utils.staticExtend = __webpack_require__(602); +utils.union = __webpack_require__(575); +utils.define = __webpack_require__(593); +utils.isObj = __webpack_require__(530); +utils.staticExtend = __webpack_require__(600); /** @@ -68481,7 +68397,7 @@ module.exports = utils; /***/ }), -/* 595 */ +/* 593 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68494,7 +68410,7 @@ module.exports = utils; -var isDescriptor = __webpack_require__(596); +var isDescriptor = __webpack_require__(594); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -68519,7 +68435,7 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 596 */ +/* 594 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68532,9 +68448,9 @@ module.exports = function defineProperty(obj, prop, val) { -var typeOf = __webpack_require__(597); -var isAccessor = __webpack_require__(598); -var isData = __webpack_require__(600); +var typeOf = __webpack_require__(595); +var isAccessor = __webpack_require__(596); +var isData = __webpack_require__(598); module.exports = function isDescriptor(obj, key) { if (typeOf(obj) !== 'object') { @@ -68548,7 +68464,7 @@ module.exports = function isDescriptor(obj, key) { /***/ }), -/* 597 */ +/* 595 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -68701,7 +68617,7 @@ function isBuffer(val) { /***/ }), -/* 598 */ +/* 596 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68714,7 +68630,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(599); +var typeOf = __webpack_require__(597); // accessor descriptor properties var accessor = { @@ -68777,10 +68693,10 @@ module.exports = isAccessorDescriptor; /***/ }), -/* 599 */ +/* 597 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(558); +var isBuffer = __webpack_require__(556); var toString = Object.prototype.toString; /** @@ -68899,7 +68815,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 600 */ +/* 598 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68912,7 +68828,7 @@ module.exports = function kindOf(val) { -var typeOf = __webpack_require__(601); +var typeOf = __webpack_require__(599); // data descriptor properties var data = { @@ -68961,10 +68877,10 @@ module.exports = isDataDescriptor; /***/ }), -/* 601 */ +/* 599 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(558); +var isBuffer = __webpack_require__(556); var toString = Object.prototype.toString; /** @@ -69083,7 +68999,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 602 */ +/* 600 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69096,8 +69012,8 @@ module.exports = function kindOf(val) { -var copy = __webpack_require__(603); -var define = __webpack_require__(595); +var copy = __webpack_require__(601); +var define = __webpack_require__(593); var util = __webpack_require__(112); /** @@ -69180,15 +69096,15 @@ module.exports = extend; /***/ }), -/* 603 */ +/* 601 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var typeOf = __webpack_require__(557); -var copyDescriptor = __webpack_require__(604); -var define = __webpack_require__(595); +var typeOf = __webpack_require__(555); +var copyDescriptor = __webpack_require__(602); +var define = __webpack_require__(593); /** * Copy static properties, prototype properties, and descriptors from one object to another. @@ -69361,7 +69277,7 @@ module.exports.has = has; /***/ }), -/* 604 */ +/* 602 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69449,16 +69365,16 @@ function isObject(val) { /***/ }), -/* 605 */ +/* 603 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var use = __webpack_require__(606); -var define = __webpack_require__(595); -var debug = __webpack_require__(608)('snapdragon:compiler'); -var utils = __webpack_require__(614); +var use = __webpack_require__(604); +var define = __webpack_require__(593); +var debug = __webpack_require__(606)('snapdragon:compiler'); +var utils = __webpack_require__(612); /** * Create a new `Compiler` with the given `options`. @@ -69612,7 +69528,7 @@ Compiler.prototype = { // source map support if (opts.sourcemap) { - var sourcemaps = __webpack_require__(633); + var sourcemaps = __webpack_require__(631); sourcemaps(this); this.mapVisit(this.ast.nodes); this.applySourceMaps(); @@ -69633,7 +69549,7 @@ module.exports = Compiler; /***/ }), -/* 606 */ +/* 604 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69646,7 +69562,7 @@ module.exports = Compiler; -var utils = __webpack_require__(607); +var utils = __webpack_require__(605); module.exports = function base(app, opts) { if (!utils.isObject(app) && typeof app !== 'function') { @@ -69761,7 +69677,7 @@ module.exports = function base(app, opts) { /***/ }), -/* 607 */ +/* 605 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69775,8 +69691,8 @@ var utils = {}; * Lazily required module dependencies */ -utils.define = __webpack_require__(595); -utils.isObject = __webpack_require__(532); +utils.define = __webpack_require__(593); +utils.isObject = __webpack_require__(530); utils.isString = function(val) { @@ -69791,7 +69707,7 @@ module.exports = utils; /***/ }), -/* 608 */ +/* 606 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -69800,14 +69716,14 @@ module.exports = utils; */ if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(609); + module.exports = __webpack_require__(607); } else { - module.exports = __webpack_require__(612); + module.exports = __webpack_require__(610); } /***/ }), -/* 609 */ +/* 607 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -69816,7 +69732,7 @@ if (typeof process !== 'undefined' && process.type === 'renderer') { * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(610); +exports = module.exports = __webpack_require__(608); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; @@ -69998,7 +69914,7 @@ function localstorage() { /***/ }), -/* 610 */ +/* 608 */ /***/ (function(module, exports, __webpack_require__) { @@ -70014,7 +69930,7 @@ exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; -exports.humanize = __webpack_require__(611); +exports.humanize = __webpack_require__(609); /** * The currently active debug mode names, and names to skip. @@ -70206,7 +70122,7 @@ function coerce(val) { /***/ }), -/* 611 */ +/* 609 */ /***/ (function(module, exports) { /** @@ -70364,7 +70280,7 @@ function plural(ms, n, name) { /***/ }), -/* 612 */ +/* 610 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -70380,7 +70296,7 @@ var util = __webpack_require__(112); * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(610); +exports = module.exports = __webpack_require__(608); exports.init = init; exports.log = log; exports.formatArgs = formatArgs; @@ -70559,7 +70475,7 @@ function createWritableStdioStream (fd) { case 'PIPE': case 'TCP': - var net = __webpack_require__(613); + var net = __webpack_require__(611); stream = new net.Socket({ fd: fd, readable: false, @@ -70618,13 +70534,13 @@ exports.enable(load()); /***/ }), -/* 613 */ +/* 611 */ /***/ (function(module, exports) { module.exports = require("net"); /***/ }), -/* 614 */ +/* 612 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -70634,9 +70550,9 @@ module.exports = require("net"); * Module dependencies */ -exports.extend = __webpack_require__(547); -exports.SourceMap = __webpack_require__(615); -exports.sourceMapResolve = __webpack_require__(626); +exports.extend = __webpack_require__(545); +exports.SourceMap = __webpack_require__(613); +exports.sourceMapResolve = __webpack_require__(624); /** * Convert backslash in the given string to forward slashes @@ -70679,7 +70595,7 @@ exports.last = function(arr, n) { /***/ }), -/* 615 */ +/* 613 */ /***/ (function(module, exports, __webpack_require__) { /* @@ -70687,13 +70603,13 @@ exports.last = function(arr, n) { * Licensed under the New BSD license. See LICENSE.txt or: * http://opensource.org/licenses/BSD-3-Clause */ -exports.SourceMapGenerator = __webpack_require__(616).SourceMapGenerator; -exports.SourceMapConsumer = __webpack_require__(622).SourceMapConsumer; -exports.SourceNode = __webpack_require__(625).SourceNode; +exports.SourceMapGenerator = __webpack_require__(614).SourceMapGenerator; +exports.SourceMapConsumer = __webpack_require__(620).SourceMapConsumer; +exports.SourceNode = __webpack_require__(623).SourceNode; /***/ }), -/* 616 */ +/* 614 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -70703,10 +70619,10 @@ exports.SourceNode = __webpack_require__(625).SourceNode; * http://opensource.org/licenses/BSD-3-Clause */ -var base64VLQ = __webpack_require__(617); -var util = __webpack_require__(619); -var ArraySet = __webpack_require__(620).ArraySet; -var MappingList = __webpack_require__(621).MappingList; +var base64VLQ = __webpack_require__(615); +var util = __webpack_require__(617); +var ArraySet = __webpack_require__(618).ArraySet; +var MappingList = __webpack_require__(619).MappingList; /** * An instance of the SourceMapGenerator represents a source map which is @@ -71115,7 +71031,7 @@ exports.SourceMapGenerator = SourceMapGenerator; /***/ }), -/* 617 */ +/* 615 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71155,7 +71071,7 @@ exports.SourceMapGenerator = SourceMapGenerator; * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -var base64 = __webpack_require__(618); +var base64 = __webpack_require__(616); // A single base 64 digit can contain 6 bits of data. For the base 64 variable // length quantities we use in the source map spec, the first bit is the sign, @@ -71261,7 +71177,7 @@ exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { /***/ }), -/* 618 */ +/* 616 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71334,7 +71250,7 @@ exports.decode = function (charCode) { /***/ }), -/* 619 */ +/* 617 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71757,7 +71673,7 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate /***/ }), -/* 620 */ +/* 618 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71767,7 +71683,7 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(619); +var util = __webpack_require__(617); var has = Object.prototype.hasOwnProperty; var hasNativeMap = typeof Map !== "undefined"; @@ -71884,7 +71800,7 @@ exports.ArraySet = ArraySet; /***/ }), -/* 621 */ +/* 619 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71894,7 +71810,7 @@ exports.ArraySet = ArraySet; * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(619); +var util = __webpack_require__(617); /** * Determine whether mappingB is after mappingA with respect to generated @@ -71969,7 +71885,7 @@ exports.MappingList = MappingList; /***/ }), -/* 622 */ +/* 620 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71979,11 +71895,11 @@ exports.MappingList = MappingList; * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(619); -var binarySearch = __webpack_require__(623); -var ArraySet = __webpack_require__(620).ArraySet; -var base64VLQ = __webpack_require__(617); -var quickSort = __webpack_require__(624).quickSort; +var util = __webpack_require__(617); +var binarySearch = __webpack_require__(621); +var ArraySet = __webpack_require__(618).ArraySet; +var base64VLQ = __webpack_require__(615); +var quickSort = __webpack_require__(622).quickSort; function SourceMapConsumer(aSourceMap) { var sourceMap = aSourceMap; @@ -73057,7 +72973,7 @@ exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; /***/ }), -/* 623 */ +/* 621 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -73174,7 +73090,7 @@ exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { /***/ }), -/* 624 */ +/* 622 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -73294,7 +73210,7 @@ exports.quickSort = function (ary, comparator) { /***/ }), -/* 625 */ +/* 623 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -73304,8 +73220,8 @@ exports.quickSort = function (ary, comparator) { * http://opensource.org/licenses/BSD-3-Clause */ -var SourceMapGenerator = __webpack_require__(616).SourceMapGenerator; -var util = __webpack_require__(619); +var SourceMapGenerator = __webpack_require__(614).SourceMapGenerator; +var util = __webpack_require__(617); // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other // operating systems these days (capturing the result). @@ -73713,17 +73629,17 @@ exports.SourceNode = SourceNode; /***/ }), -/* 626 */ +/* 624 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014, 2015, 2016, 2017 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var sourceMappingURL = __webpack_require__(627) -var resolveUrl = __webpack_require__(628) -var decodeUriComponent = __webpack_require__(629) -var urix = __webpack_require__(631) -var atob = __webpack_require__(632) +var sourceMappingURL = __webpack_require__(625) +var resolveUrl = __webpack_require__(626) +var decodeUriComponent = __webpack_require__(627) +var urix = __webpack_require__(629) +var atob = __webpack_require__(630) @@ -74021,7 +73937,7 @@ module.exports = { /***/ }), -/* 627 */ +/* 625 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;// Copyright 2014 Simon Lydell @@ -74084,7 +74000,7 @@ void (function(root, factory) { /***/ }), -/* 628 */ +/* 626 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014 Simon Lydell @@ -74102,13 +74018,13 @@ module.exports = resolveUrl /***/ }), -/* 629 */ +/* 627 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2017 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var decodeUriComponent = __webpack_require__(630) +var decodeUriComponent = __webpack_require__(628) function customDecodeUriComponent(string) { // `decodeUriComponent` turns `+` into ` `, but that's not wanted. @@ -74119,7 +74035,7 @@ module.exports = customDecodeUriComponent /***/ }), -/* 630 */ +/* 628 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -74220,7 +74136,7 @@ module.exports = function (encodedURI) { /***/ }), -/* 631 */ +/* 629 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014 Simon Lydell @@ -74243,7 +74159,7 @@ module.exports = urix /***/ }), -/* 632 */ +/* 630 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -74257,7 +74173,7 @@ module.exports = atob.atob = atob; /***/ }), -/* 633 */ +/* 631 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -74265,8 +74181,8 @@ module.exports = atob.atob = atob; var fs = __webpack_require__(134); var path = __webpack_require__(4); -var define = __webpack_require__(595); -var utils = __webpack_require__(614); +var define = __webpack_require__(593); +var utils = __webpack_require__(612); /** * Expose `mixin()`. @@ -74409,19 +74325,19 @@ exports.comment = function(node) { /***/ }), -/* 634 */ +/* 632 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var use = __webpack_require__(606); +var use = __webpack_require__(604); var util = __webpack_require__(112); -var Cache = __webpack_require__(635); -var define = __webpack_require__(595); -var debug = __webpack_require__(608)('snapdragon:parser'); -var Position = __webpack_require__(636); -var utils = __webpack_require__(614); +var Cache = __webpack_require__(633); +var define = __webpack_require__(593); +var debug = __webpack_require__(606)('snapdragon:parser'); +var Position = __webpack_require__(634); +var utils = __webpack_require__(612); /** * Create a new `Parser` with the given `input` and `options`. @@ -74949,7 +74865,7 @@ module.exports = Parser; /***/ }), -/* 635 */ +/* 633 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -75056,13 +74972,13 @@ MapCache.prototype.del = function mapDelete(key) { /***/ }), -/* 636 */ +/* 634 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var define = __webpack_require__(595); +var define = __webpack_require__(593); /** * Store position for a node @@ -75077,14 +74993,14 @@ module.exports = function Position(start, parser) { /***/ }), -/* 637 */ +/* 635 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(638); -var assignSymbols = __webpack_require__(542); +var isExtendable = __webpack_require__(636); +var assignSymbols = __webpack_require__(540); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -75144,7 +75060,7 @@ function isEnum(obj, key) { /***/ }), -/* 638 */ +/* 636 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -75157,7 +75073,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(541); +var isPlainObject = __webpack_require__(539); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -75165,14 +75081,14 @@ module.exports = function isExtendable(val) { /***/ }), -/* 639 */ +/* 637 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var nanomatch = __webpack_require__(640); -var extglob = __webpack_require__(655); +var nanomatch = __webpack_require__(638); +var extglob = __webpack_require__(653); module.exports = function(snapdragon) { var compilers = snapdragon.compiler.compilers; @@ -75249,7 +75165,7 @@ function escapeExtglobs(compiler) { /***/ }), -/* 640 */ +/* 638 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -75260,17 +75176,17 @@ function escapeExtglobs(compiler) { */ var util = __webpack_require__(112); -var toRegex = __webpack_require__(524); -var extend = __webpack_require__(641); +var toRegex = __webpack_require__(522); +var extend = __webpack_require__(639); /** * Local dependencies */ -var compilers = __webpack_require__(643); -var parsers = __webpack_require__(644); -var cache = __webpack_require__(647); -var utils = __webpack_require__(649); +var compilers = __webpack_require__(641); +var parsers = __webpack_require__(642); +var cache = __webpack_require__(645); +var utils = __webpack_require__(647); var MAX_LENGTH = 1024 * 64; /** @@ -76094,14 +76010,14 @@ module.exports = nanomatch; /***/ }), -/* 641 */ +/* 639 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(642); -var assignSymbols = __webpack_require__(542); +var isExtendable = __webpack_require__(640); +var assignSymbols = __webpack_require__(540); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -76161,7 +76077,7 @@ function isEnum(obj, key) { /***/ }), -/* 642 */ +/* 640 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -76174,7 +76090,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(541); +var isPlainObject = __webpack_require__(539); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -76182,7 +76098,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 643 */ +/* 641 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -76528,15 +76444,15 @@ module.exports = function(nanomatch, options) { /***/ }), -/* 644 */ +/* 642 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var regexNot = __webpack_require__(543); -var toRegex = __webpack_require__(524); -var isOdd = __webpack_require__(645); +var regexNot = __webpack_require__(541); +var toRegex = __webpack_require__(522); +var isOdd = __webpack_require__(643); /** * Characters to use in negation regex (we want to "not" match @@ -76922,7 +76838,7 @@ module.exports.not = NOT_REGEX; /***/ }), -/* 645 */ +/* 643 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -76935,7 +76851,7 @@ module.exports.not = NOT_REGEX; -var isNumber = __webpack_require__(646); +var isNumber = __webpack_require__(644); module.exports = function isOdd(i) { if (!isNumber(i)) { @@ -76949,7 +76865,7 @@ module.exports = function isOdd(i) { /***/ }), -/* 646 */ +/* 644 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -76977,14 +76893,14 @@ module.exports = function isNumber(num) { /***/ }), -/* 647 */ +/* 645 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(648))(); +module.exports = new (__webpack_require__(646))(); /***/ }), -/* 648 */ +/* 646 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -76997,7 +76913,7 @@ module.exports = new (__webpack_require__(648))(); -var MapCache = __webpack_require__(635); +var MapCache = __webpack_require__(633); /** * Create a new `FragmentCache` with an optional object to use for `caches`. @@ -77119,7 +77035,7 @@ exports = module.exports = FragmentCache; /***/ }), -/* 649 */ +/* 647 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77132,14 +77048,14 @@ var path = __webpack_require__(4); * Module dependencies */ -var isWindows = __webpack_require__(650)(); -var Snapdragon = __webpack_require__(567); -utils.define = __webpack_require__(651); -utils.diff = __webpack_require__(652); -utils.extend = __webpack_require__(641); -utils.pick = __webpack_require__(653); -utils.typeOf = __webpack_require__(654); -utils.unique = __webpack_require__(546); +var isWindows = __webpack_require__(648)(); +var Snapdragon = __webpack_require__(565); +utils.define = __webpack_require__(649); +utils.diff = __webpack_require__(650); +utils.extend = __webpack_require__(639); +utils.pick = __webpack_require__(651); +utils.typeOf = __webpack_require__(652); +utils.unique = __webpack_require__(544); /** * Returns true if the given value is effectively an empty string @@ -77505,7 +77421,7 @@ utils.unixify = function(options) { /***/ }), -/* 650 */ +/* 648 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! @@ -77533,7 +77449,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ /***/ }), -/* 651 */ +/* 649 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77546,8 +77462,8 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ -var isobject = __webpack_require__(532); -var isDescriptor = __webpack_require__(533); +var isobject = __webpack_require__(530); +var isDescriptor = __webpack_require__(531); var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) ? Reflect.defineProperty : Object.defineProperty; @@ -77578,7 +77494,7 @@ module.exports = function defineProperty(obj, key, val) { /***/ }), -/* 652 */ +/* 650 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77632,7 +77548,7 @@ function diffArray(one, two) { /***/ }), -/* 653 */ +/* 651 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77645,7 +77561,7 @@ function diffArray(one, two) { -var isObject = __webpack_require__(532); +var isObject = __webpack_require__(530); module.exports = function pick(obj, keys) { if (!isObject(obj) && typeof obj !== 'function') { @@ -77674,7 +77590,7 @@ module.exports = function pick(obj, keys) { /***/ }), -/* 654 */ +/* 652 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -77809,7 +77725,7 @@ function isBuffer(val) { /***/ }), -/* 655 */ +/* 653 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77819,18 +77735,18 @@ function isBuffer(val) { * Module dependencies */ -var extend = __webpack_require__(547); -var unique = __webpack_require__(546); -var toRegex = __webpack_require__(524); +var extend = __webpack_require__(545); +var unique = __webpack_require__(544); +var toRegex = __webpack_require__(522); /** * Local dependencies */ -var compilers = __webpack_require__(656); -var parsers = __webpack_require__(662); -var Extglob = __webpack_require__(665); -var utils = __webpack_require__(664); +var compilers = __webpack_require__(654); +var parsers = __webpack_require__(660); +var Extglob = __webpack_require__(663); +var utils = __webpack_require__(662); var MAX_LENGTH = 1024 * 64; /** @@ -78147,13 +78063,13 @@ module.exports = extglob; /***/ }), -/* 656 */ +/* 654 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(657); +var brackets = __webpack_require__(655); /** * Extglob compilers @@ -78323,7 +78239,7 @@ module.exports = function(extglob) { /***/ }), -/* 657 */ +/* 655 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78333,17 +78249,17 @@ module.exports = function(extglob) { * Local dependencies */ -var compilers = __webpack_require__(658); -var parsers = __webpack_require__(660); +var compilers = __webpack_require__(656); +var parsers = __webpack_require__(658); /** * Module dependencies */ -var debug = __webpack_require__(608)('expand-brackets'); -var extend = __webpack_require__(547); -var Snapdragon = __webpack_require__(567); -var toRegex = __webpack_require__(524); +var debug = __webpack_require__(606)('expand-brackets'); +var extend = __webpack_require__(545); +var Snapdragon = __webpack_require__(565); +var toRegex = __webpack_require__(522); /** * Parses the given POSIX character class `pattern` and returns a @@ -78541,13 +78457,13 @@ module.exports = brackets; /***/ }), -/* 658 */ +/* 656 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var posix = __webpack_require__(659); +var posix = __webpack_require__(657); module.exports = function(brackets) { brackets.compiler @@ -78635,7 +78551,7 @@ module.exports = function(brackets) { /***/ }), -/* 659 */ +/* 657 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78664,14 +78580,14 @@ module.exports = { /***/ }), -/* 660 */ +/* 658 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(661); -var define = __webpack_require__(595); +var utils = __webpack_require__(659); +var define = __webpack_require__(593); /** * Text regex @@ -78890,14 +78806,14 @@ module.exports.TEXT_REGEX = TEXT_REGEX; /***/ }), -/* 661 */ +/* 659 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var toRegex = __webpack_require__(524); -var regexNot = __webpack_require__(543); +var toRegex = __webpack_require__(522); +var regexNot = __webpack_require__(541); var cached; /** @@ -78931,15 +78847,15 @@ exports.createRegex = function(pattern, include) { /***/ }), -/* 662 */ +/* 660 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(657); -var define = __webpack_require__(663); -var utils = __webpack_require__(664); +var brackets = __webpack_require__(655); +var define = __webpack_require__(661); +var utils = __webpack_require__(662); /** * Characters to use in text regex (we want to "not" match @@ -79094,7 +79010,7 @@ module.exports = parsers; /***/ }), -/* 663 */ +/* 661 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79107,7 +79023,7 @@ module.exports = parsers; -var isDescriptor = __webpack_require__(533); +var isDescriptor = __webpack_require__(531); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -79132,14 +79048,14 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 664 */ +/* 662 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var regex = __webpack_require__(543); -var Cache = __webpack_require__(648); +var regex = __webpack_require__(541); +var Cache = __webpack_require__(646); /** * Utils @@ -79208,7 +79124,7 @@ utils.createRegex = function(str) { /***/ }), -/* 665 */ +/* 663 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79218,16 +79134,16 @@ utils.createRegex = function(str) { * Module dependencies */ -var Snapdragon = __webpack_require__(567); -var define = __webpack_require__(663); -var extend = __webpack_require__(547); +var Snapdragon = __webpack_require__(565); +var define = __webpack_require__(661); +var extend = __webpack_require__(545); /** * Local dependencies */ -var compilers = __webpack_require__(656); -var parsers = __webpack_require__(662); +var compilers = __webpack_require__(654); +var parsers = __webpack_require__(660); /** * Customize Snapdragon parser and renderer @@ -79293,16 +79209,16 @@ module.exports = Extglob; /***/ }), -/* 666 */ +/* 664 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extglob = __webpack_require__(655); -var nanomatch = __webpack_require__(640); -var regexNot = __webpack_require__(543); -var toRegex = __webpack_require__(524); +var extglob = __webpack_require__(653); +var nanomatch = __webpack_require__(638); +var regexNot = __webpack_require__(541); +var toRegex = __webpack_require__(522); var not; /** @@ -79383,14 +79299,14 @@ function textRegex(pattern) { /***/ }), -/* 667 */ +/* 665 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(648))(); +module.exports = new (__webpack_require__(646))(); /***/ }), -/* 668 */ +/* 666 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79403,13 +79319,13 @@ var path = __webpack_require__(4); * Module dependencies */ -var Snapdragon = __webpack_require__(567); -utils.define = __webpack_require__(669); -utils.diff = __webpack_require__(652); -utils.extend = __webpack_require__(637); -utils.pick = __webpack_require__(653); -utils.typeOf = __webpack_require__(670); -utils.unique = __webpack_require__(546); +var Snapdragon = __webpack_require__(565); +utils.define = __webpack_require__(667); +utils.diff = __webpack_require__(650); +utils.extend = __webpack_require__(635); +utils.pick = __webpack_require__(651); +utils.typeOf = __webpack_require__(668); +utils.unique = __webpack_require__(544); /** * Returns true if the platform is windows, or `path.sep` is `\\`. @@ -79706,7 +79622,7 @@ utils.unixify = function(options) { /***/ }), -/* 669 */ +/* 667 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79719,8 +79635,8 @@ utils.unixify = function(options) { -var isobject = __webpack_require__(532); -var isDescriptor = __webpack_require__(533); +var isobject = __webpack_require__(530); +var isDescriptor = __webpack_require__(531); var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) ? Reflect.defineProperty : Object.defineProperty; @@ -79751,7 +79667,7 @@ module.exports = function defineProperty(obj, key, val) { /***/ }), -/* 670 */ +/* 668 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -79886,7 +79802,7 @@ function isBuffer(val) { /***/ }), -/* 671 */ +/* 669 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79905,9 +79821,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(672); -var reader_1 = __webpack_require__(685); -var fs_stream_1 = __webpack_require__(689); +var readdir = __webpack_require__(670); +var reader_1 = __webpack_require__(683); +var fs_stream_1 = __webpack_require__(687); var ReaderAsync = /** @class */ (function (_super) { __extends(ReaderAsync, _super); function ReaderAsync() { @@ -79968,15 +79884,15 @@ exports.default = ReaderAsync; /***/ }), -/* 672 */ +/* 670 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const readdirSync = __webpack_require__(673); -const readdirAsync = __webpack_require__(681); -const readdirStream = __webpack_require__(684); +const readdirSync = __webpack_require__(671); +const readdirAsync = __webpack_require__(679); +const readdirStream = __webpack_require__(682); module.exports = exports = readdirAsyncPath; exports.readdir = exports.readdirAsync = exports.async = readdirAsyncPath; @@ -80060,7 +79976,7 @@ function readdirStreamStat (dir, options) { /***/ }), -/* 673 */ +/* 671 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80068,11 +79984,11 @@ function readdirStreamStat (dir, options) { module.exports = readdirSync; -const DirectoryReader = __webpack_require__(674); +const DirectoryReader = __webpack_require__(672); let syncFacade = { - fs: __webpack_require__(679), - forEach: __webpack_require__(680), + fs: __webpack_require__(677), + forEach: __webpack_require__(678), sync: true }; @@ -80101,7 +80017,7 @@ function readdirSync (dir, options, internalOptions) { /***/ }), -/* 674 */ +/* 672 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80110,9 +80026,9 @@ function readdirSync (dir, options, internalOptions) { const Readable = __webpack_require__(138).Readable; const EventEmitter = __webpack_require__(156).EventEmitter; const path = __webpack_require__(4); -const normalizeOptions = __webpack_require__(675); -const stat = __webpack_require__(677); -const call = __webpack_require__(678); +const normalizeOptions = __webpack_require__(673); +const stat = __webpack_require__(675); +const call = __webpack_require__(676); /** * Asynchronously reads the contents of a directory and streams the results @@ -80488,14 +80404,14 @@ module.exports = DirectoryReader; /***/ }), -/* 675 */ +/* 673 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const globToRegExp = __webpack_require__(676); +const globToRegExp = __webpack_require__(674); module.exports = normalizeOptions; @@ -80672,7 +80588,7 @@ function normalizeOptions (options, internalOptions) { /***/ }), -/* 676 */ +/* 674 */ /***/ (function(module, exports) { module.exports = function (glob, opts) { @@ -80809,13 +80725,13 @@ module.exports = function (glob, opts) { /***/ }), -/* 677 */ +/* 675 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const call = __webpack_require__(678); +const call = __webpack_require__(676); module.exports = stat; @@ -80890,7 +80806,7 @@ function symlinkStat (fs, path, lstats, callback) { /***/ }), -/* 678 */ +/* 676 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80951,14 +80867,14 @@ function callOnce (fn) { /***/ }), -/* 679 */ +/* 677 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(134); -const call = __webpack_require__(678); +const call = __webpack_require__(676); /** * A facade around {@link fs.readdirSync} that allows it to be called @@ -81022,7 +80938,7 @@ exports.lstat = function (path, callback) { /***/ }), -/* 680 */ +/* 678 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81051,7 +80967,7 @@ function syncForEach (array, iterator, done) { /***/ }), -/* 681 */ +/* 679 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81059,12 +80975,12 @@ function syncForEach (array, iterator, done) { module.exports = readdirAsync; -const maybe = __webpack_require__(682); -const DirectoryReader = __webpack_require__(674); +const maybe = __webpack_require__(680); +const DirectoryReader = __webpack_require__(672); let asyncFacade = { fs: __webpack_require__(134), - forEach: __webpack_require__(683), + forEach: __webpack_require__(681), async: true }; @@ -81106,7 +81022,7 @@ function readdirAsync (dir, options, callback, internalOptions) { /***/ }), -/* 682 */ +/* 680 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81133,7 +81049,7 @@ module.exports = function maybe (cb, promise) { /***/ }), -/* 683 */ +/* 681 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81169,7 +81085,7 @@ function asyncForEach (array, iterator, done) { /***/ }), -/* 684 */ +/* 682 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81177,11 +81093,11 @@ function asyncForEach (array, iterator, done) { module.exports = readdirStream; -const DirectoryReader = __webpack_require__(674); +const DirectoryReader = __webpack_require__(672); let streamFacade = { fs: __webpack_require__(134), - forEach: __webpack_require__(683), + forEach: __webpack_require__(681), async: true }; @@ -81201,16 +81117,16 @@ function readdirStream (dir, options, internalOptions) { /***/ }), -/* 685 */ +/* 683 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var path = __webpack_require__(4); -var deep_1 = __webpack_require__(686); -var entry_1 = __webpack_require__(688); -var pathUtil = __webpack_require__(687); +var deep_1 = __webpack_require__(684); +var entry_1 = __webpack_require__(686); +var pathUtil = __webpack_require__(685); var Reader = /** @class */ (function () { function Reader(options) { this.options = options; @@ -81276,14 +81192,14 @@ exports.default = Reader; /***/ }), -/* 686 */ +/* 684 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(687); -var patternUtils = __webpack_require__(518); +var pathUtils = __webpack_require__(685); +var patternUtils = __webpack_require__(516); var DeepFilter = /** @class */ (function () { function DeepFilter(options, micromatchOptions) { this.options = options; @@ -81366,7 +81282,7 @@ exports.default = DeepFilter; /***/ }), -/* 687 */ +/* 685 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81397,14 +81313,14 @@ exports.makeAbsolute = makeAbsolute; /***/ }), -/* 688 */ +/* 686 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(687); -var patternUtils = __webpack_require__(518); +var pathUtils = __webpack_require__(685); +var patternUtils = __webpack_require__(516); var EntryFilter = /** @class */ (function () { function EntryFilter(options, micromatchOptions) { this.options = options; @@ -81489,7 +81405,7 @@ exports.default = EntryFilter; /***/ }), -/* 689 */ +/* 687 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81509,8 +81425,8 @@ var __extends = (this && this.__extends) || (function () { })(); Object.defineProperty(exports, "__esModule", { value: true }); var stream = __webpack_require__(138); -var fsStat = __webpack_require__(690); -var fs_1 = __webpack_require__(694); +var fsStat = __webpack_require__(688); +var fs_1 = __webpack_require__(692); var FileSystemStream = /** @class */ (function (_super) { __extends(FileSystemStream, _super); function FileSystemStream() { @@ -81560,14 +81476,14 @@ exports.default = FileSystemStream; /***/ }), -/* 690 */ +/* 688 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const optionsManager = __webpack_require__(691); -const statProvider = __webpack_require__(693); +const optionsManager = __webpack_require__(689); +const statProvider = __webpack_require__(691); /** * Asynchronous API. */ @@ -81598,13 +81514,13 @@ exports.statSync = statSync; /***/ }), -/* 691 */ +/* 689 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsAdapter = __webpack_require__(692); +const fsAdapter = __webpack_require__(690); function prepare(opts) { const options = Object.assign({ fs: fsAdapter.getFileSystemAdapter(opts ? opts.fs : undefined), @@ -81617,7 +81533,7 @@ exports.prepare = prepare; /***/ }), -/* 692 */ +/* 690 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81640,7 +81556,7 @@ exports.getFileSystemAdapter = getFileSystemAdapter; /***/ }), -/* 693 */ +/* 691 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81692,7 +81608,7 @@ exports.isFollowedSymlink = isFollowedSymlink; /***/ }), -/* 694 */ +/* 692 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81723,7 +81639,7 @@ exports.default = FileSystem; /***/ }), -/* 695 */ +/* 693 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81743,9 +81659,9 @@ var __extends = (this && this.__extends) || (function () { })(); Object.defineProperty(exports, "__esModule", { value: true }); var stream = __webpack_require__(138); -var readdir = __webpack_require__(672); -var reader_1 = __webpack_require__(685); -var fs_stream_1 = __webpack_require__(689); +var readdir = __webpack_require__(670); +var reader_1 = __webpack_require__(683); +var fs_stream_1 = __webpack_require__(687); var TransformStream = /** @class */ (function (_super) { __extends(TransformStream, _super); function TransformStream(reader) { @@ -81813,7 +81729,7 @@ exports.default = ReaderStream; /***/ }), -/* 696 */ +/* 694 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81832,9 +81748,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(672); -var reader_1 = __webpack_require__(685); -var fs_sync_1 = __webpack_require__(697); +var readdir = __webpack_require__(670); +var reader_1 = __webpack_require__(683); +var fs_sync_1 = __webpack_require__(695); var ReaderSync = /** @class */ (function (_super) { __extends(ReaderSync, _super); function ReaderSync() { @@ -81894,7 +81810,7 @@ exports.default = ReaderSync; /***/ }), -/* 697 */ +/* 695 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81913,8 +81829,8 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var fsStat = __webpack_require__(690); -var fs_1 = __webpack_require__(694); +var fsStat = __webpack_require__(688); +var fs_1 = __webpack_require__(692); var FileSystemSync = /** @class */ (function (_super) { __extends(FileSystemSync, _super); function FileSystemSync() { @@ -81960,7 +81876,7 @@ exports.default = FileSystemSync; /***/ }), -/* 698 */ +/* 696 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81976,7 +81892,7 @@ exports.flatten = flatten; /***/ }), -/* 699 */ +/* 697 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81997,13 +81913,13 @@ exports.merge = merge; /***/ }), -/* 700 */ +/* 698 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const pathType = __webpack_require__(701); +const pathType = __webpack_require__(699); const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; @@ -82069,13 +81985,13 @@ module.exports.sync = (input, opts) => { /***/ }), -/* 701 */ +/* 699 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(134); -const pify = __webpack_require__(702); +const pify = __webpack_require__(700); function type(fn, fn2, fp) { if (typeof fp !== 'string') { @@ -82118,7 +82034,7 @@ exports.symlinkSync = typeSync.bind(null, 'lstatSync', 'isSymbolicLink'); /***/ }), -/* 702 */ +/* 700 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82209,17 +82125,17 @@ module.exports = (obj, opts) => { /***/ }), -/* 703 */ +/* 701 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(134); const path = __webpack_require__(4); -const fastGlob = __webpack_require__(514); -const gitIgnore = __webpack_require__(704); -const pify = __webpack_require__(705); -const slash = __webpack_require__(706); +const fastGlob = __webpack_require__(512); +const gitIgnore = __webpack_require__(702); +const pify = __webpack_require__(703); +const slash = __webpack_require__(704); const DEFAULT_IGNORE = [ '**/node_modules/**', @@ -82317,7 +82233,7 @@ module.exports.sync = options => { /***/ }), -/* 704 */ +/* 702 */ /***/ (function(module, exports) { // A simple implementation of make-array @@ -82786,7 +82702,7 @@ module.exports = options => new IgnoreBase(options) /***/ }), -/* 705 */ +/* 703 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82861,7 +82777,7 @@ module.exports = (input, options) => { /***/ }), -/* 706 */ +/* 704 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82879,7 +82795,7 @@ module.exports = input => { /***/ }), -/* 707 */ +/* 705 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82892,7 +82808,7 @@ module.exports = input => { -var isGlob = __webpack_require__(708); +var isGlob = __webpack_require__(706); module.exports = function hasGlob(val) { if (val == null) return false; @@ -82912,7 +82828,7 @@ module.exports = function hasGlob(val) { /***/ }), -/* 708 */ +/* 706 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -82943,17 +82859,17 @@ module.exports = function isGlob(str) { /***/ }), -/* 709 */ +/* 707 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); const {constants: fsConstants} = __webpack_require__(134); -const pEvent = __webpack_require__(710); -const CpFileError = __webpack_require__(713); -const fs = __webpack_require__(715); -const ProgressEmitter = __webpack_require__(718); +const pEvent = __webpack_require__(708); +const CpFileError = __webpack_require__(711); +const fs = __webpack_require__(713); +const ProgressEmitter = __webpack_require__(716); const cpFileAsync = async (source, destination, options, progressEmitter) => { let readError; @@ -83067,12 +82983,12 @@ module.exports.sync = (source, destination, options) => { /***/ }), -/* 710 */ +/* 708 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pTimeout = __webpack_require__(711); +const pTimeout = __webpack_require__(709); const symbolAsyncIterator = Symbol.asyncIterator || '@@asyncIterator'; @@ -83363,12 +83279,12 @@ module.exports.iterator = (emitter, event, options) => { /***/ }), -/* 711 */ +/* 709 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pFinally = __webpack_require__(712); +const pFinally = __webpack_require__(710); class TimeoutError extends Error { constructor(message) { @@ -83414,7 +83330,7 @@ module.exports.TimeoutError = TimeoutError; /***/ }), -/* 712 */ +/* 710 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83436,12 +83352,12 @@ module.exports = (promise, onFinally) => { /***/ }), -/* 713 */ +/* 711 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(714); +const NestedError = __webpack_require__(712); class CpFileError extends NestedError { constructor(message, nested) { @@ -83455,7 +83371,7 @@ module.exports = CpFileError; /***/ }), -/* 714 */ +/* 712 */ /***/ (function(module, exports, __webpack_require__) { var inherits = __webpack_require__(112).inherits; @@ -83511,16 +83427,16 @@ module.exports = NestedError; /***/ }), -/* 715 */ +/* 713 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const {promisify} = __webpack_require__(112); const fs = __webpack_require__(133); -const makeDir = __webpack_require__(716); -const pEvent = __webpack_require__(710); -const CpFileError = __webpack_require__(713); +const makeDir = __webpack_require__(714); +const pEvent = __webpack_require__(708); +const CpFileError = __webpack_require__(711); const stat = promisify(fs.stat); const lstat = promisify(fs.lstat); @@ -83617,7 +83533,7 @@ exports.copyFileSync = (source, destination, flags) => { /***/ }), -/* 716 */ +/* 714 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83625,7 +83541,7 @@ exports.copyFileSync = (source, destination, flags) => { const fs = __webpack_require__(134); const path = __webpack_require__(4); const {promisify} = __webpack_require__(112); -const semver = __webpack_require__(717); +const semver = __webpack_require__(715); const useNativeRecursiveOption = semver.satisfies(process.version, '>=10.12.0'); @@ -83780,7 +83696,7 @@ module.exports.sync = (input, options) => { /***/ }), -/* 717 */ +/* 715 */ /***/ (function(module, exports) { exports = module.exports = SemVer @@ -85382,7 +85298,7 @@ function coerce (version, options) { /***/ }), -/* 718 */ +/* 716 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85423,7 +85339,7 @@ module.exports = ProgressEmitter; /***/ }), -/* 719 */ +/* 717 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85469,12 +85385,12 @@ exports.default = module.exports; /***/ }), -/* 720 */ +/* 718 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pMap = __webpack_require__(721); +const pMap = __webpack_require__(719); const pFilter = async (iterable, filterer, options) => { const values = await pMap( @@ -85491,7 +85407,7 @@ module.exports.default = pFilter; /***/ }), -/* 721 */ +/* 719 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85570,12 +85486,12 @@ module.exports.default = pMap; /***/ }), -/* 722 */ +/* 720 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(714); +const NestedError = __webpack_require__(712); class CpyError extends NestedError { constructor(message, nested) { diff --git a/packages/kbn-ui-framework/generator-kui/app/documentation.js b/packages/kbn-ui-framework/generator-kui/app/documentation.js deleted file mode 100644 index 3cbc0263789c65..00000000000000 --- a/packages/kbn-ui-framework/generator-kui/app/documentation.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -const Generator = require('yeoman-generator'); - -const documentationGenerator = require.resolve('../documentation/index.js'); - -module.exports = class extends Generator { - prompting() { - return this.prompt([ - { - message: 'What do you want to create?', - name: 'fileType', - type: 'list', - choices: [ - { - name: 'Page', - value: 'documentation', - }, - { - name: 'Page demo', - value: 'demo', - }, - { - name: 'Sandbox', - value: 'sandbox', - }, - ], - }, - ]).then((answers) => { - this.config = answers; - }); - } - - writing() { - this.composeWith(documentationGenerator, { - fileType: this.config.fileType, - }); - } -}; diff --git a/packages/kbn-ui-framework/generator-kui/component/index.js b/packages/kbn-ui-framework/generator-kui/component/index.js deleted file mode 100644 index 56c49fe6fa4717..00000000000000 --- a/packages/kbn-ui-framework/generator-kui/component/index.js +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -const chalk = require('chalk'); -const { resolve } = require('path'); -const Generator = require('yeoman-generator'); -const utils = require('../utils'); - -module.exports = class extends Generator { - constructor(args, options) { - super(args, options); - - this.fileType = options.fileType; - } - - prompting() { - return this.prompt([ - { - message: "What's the name of this component? Use snake_case, please.", - name: 'name', - type: 'input', - }, - { - message: `Where do you want to create this component's files?`, - type: 'input', - name: 'path', - default: resolve(__dirname, '../../src/components'), - store: true, - }, - { - message: 'Does it need its own directory?', - name: 'shouldMakeDirectory', - type: 'confirm', - default: true, - }, - ]).then((answers) => { - this.config = answers; - - if (!answers.name || !answers.name.trim()) { - this.log.error('Sorry, please run this generator again and provide a component name.'); - process.exit(1); - } - }); - } - - writing() { - const config = this.config; - - const writeComponent = (isStatelessFunction) => { - const componentName = utils.makeComponentName(config.name); - const cssClassName = utils.lowerCaseFirstLetter(componentName); - const fileName = config.name; - - const path = utils.addDirectoryToPath(config.path, fileName, config.shouldMakeDirectory); - - const vars = (config.vars = { - componentName, - cssClassName, - fileName, - }); - - const componentPath = (config.componentPath = `${path}/${fileName}.js`); - const testPath = (config.testPath = `${path}/${fileName}.test.js`); - const stylesPath = (config.stylesPath = `${path}/_${fileName}.scss`); - config.stylesImportPath = `./_${fileName}.scss`; - - // If it needs its own directory then it will need a root index file too. - if (this.config.shouldMakeDirectory) { - this.fs.copyTpl( - this.templatePath('_index.scss'), - this.destinationPath(`${path}/_index.scss`), - vars - ); - - this.fs.copyTpl( - this.templatePath('index.js'), - this.destinationPath(`${path}/index.js`), - vars - ); - } - - // Create component file. - this.fs.copyTpl( - isStatelessFunction - ? this.templatePath('stateless_function.js') - : this.templatePath('component.js'), - this.destinationPath(componentPath), - vars - ); - - // Create component test file. - this.fs.copyTpl(this.templatePath('test.js'), this.destinationPath(testPath), vars); - - // Create component styles file. - this.fs.copyTpl(this.templatePath('_component.scss'), this.destinationPath(stylesPath), vars); - }; - - switch (this.fileType) { - case 'component': - writeComponent(); - break; - - case 'function': - writeComponent(true); - break; - } - } - - end() { - const showImportComponentSnippet = () => { - const componentName = this.config.vars.componentName; - - this.log(chalk.white(`\n// Export component (e.. from component's index.js).`)); - this.log( - `${chalk.magenta('export')} {\n` + - ` ${componentName},\n` + - `} ${chalk.magenta('from')} ${chalk.cyan(`'./${this.config.name}'`)};` - ); - - this.log(chalk.white('\n// Import styles.')); - this.log(`${chalk.magenta('@import')} ${chalk.cyan(`'${this.config.name}'`)};`); - - this.log(chalk.white('\n// Import component styles into the root index.scss.')); - this.log(`${chalk.magenta('@import')} ${chalk.cyan(`'${this.config.name}/index'`)};`); - }; - - this.log('------------------------------------------------'); - this.log(chalk.bold('Handy snippets:')); - switch (this.fileType) { - case 'component': - showImportComponentSnippet(); - break; - - case 'function': - showImportComponentSnippet(); - break; - } - this.log('------------------------------------------------'); - } -}; diff --git a/packages/kbn-ui-framework/generator-kui/component/templates/_component.scss b/packages/kbn-ui-framework/generator-kui/component/templates/_component.scss deleted file mode 100644 index 668cabce61327d..00000000000000 --- a/packages/kbn-ui-framework/generator-kui/component/templates/_component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.<%= cssClassName %> { - -} diff --git a/packages/kbn-ui-framework/generator-kui/component/templates/_index.scss b/packages/kbn-ui-framework/generator-kui/component/templates/_index.scss deleted file mode 100644 index 088dee98749468..00000000000000 --- a/packages/kbn-ui-framework/generator-kui/component/templates/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import '<%= fileName %>'; diff --git a/packages/kbn-ui-framework/generator-kui/component/templates/component.js b/packages/kbn-ui-framework/generator-kui/component/templates/component.js deleted file mode 100644 index 31e362222471ad..00000000000000 --- a/packages/kbn-ui-framework/generator-kui/component/templates/component.js +++ /dev/null @@ -1,35 +0,0 @@ -import React, { - Component, -} from 'react'; -import PropTypes from 'prop-types'; -import classNames from 'classnames'; - -export class <%= componentName %> extends Component { - static propTypes = { - children: PropTypes.node, - className: PropTypes.string, - } - - constructor(props) { - super(props); - } - - render() { - const { - children, - className, - ...rest - } = this.props; - - const classes = classNames('<%= cssClassName %>', className); - - return ( -
- {children} -
- ); - } -} diff --git a/packages/kbn-ui-framework/generator-kui/component/templates/index.js b/packages/kbn-ui-framework/generator-kui/component/templates/index.js deleted file mode 100644 index 1da6deaa79d9ae..00000000000000 --- a/packages/kbn-ui-framework/generator-kui/component/templates/index.js +++ /dev/null @@ -1,3 +0,0 @@ -export { - <%= componentName %>, -} from './<%= fileName %>'; diff --git a/packages/kbn-ui-framework/generator-kui/component/templates/stateless_function.js b/packages/kbn-ui-framework/generator-kui/component/templates/stateless_function.js deleted file mode 100644 index 7fcbf0c19d728e..00000000000000 --- a/packages/kbn-ui-framework/generator-kui/component/templates/stateless_function.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import classNames from 'classnames'; - -export const <%= componentName %> = ({ - children, - className, - ...rest -}) => { - const classes = classNames('<%= cssClassName %>', className); - - return ( -
- {children} -
- ); -}; - -<%= componentName %>.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -}; diff --git a/packages/kbn-ui-framework/generator-kui/component/templates/test.js b/packages/kbn-ui-framework/generator-kui/component/templates/test.js deleted file mode 100644 index 4f384d6c2d3aa0..00000000000000 --- a/packages/kbn-ui-framework/generator-kui/component/templates/test.js +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react'; -import { render } from 'enzyme'; -import { requiredProps } from '../../test/required_props'; - -import { <%= componentName %> } from './<%= fileName %>'; - -describe('<%= componentName %>', () => { - test('is rendered', () => { - const component = render( - <<%= componentName %> {...requiredProps} /> - ); - - expect(component) - .toMatchSnapshot(); - }); -}); diff --git a/packages/kbn-ui-framework/generator-kui/documentation/index.js b/packages/kbn-ui-framework/generator-kui/documentation/index.js deleted file mode 100644 index 03f8d5813b2515..00000000000000 --- a/packages/kbn-ui-framework/generator-kui/documentation/index.js +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -const chalk = require('chalk'); -const { resolve } = require('path'); -const Generator = require('yeoman-generator'); -const utils = require('../utils'); - -const DOCUMENTATION_PAGE_PATH = resolve(__dirname, '../../doc_site/src/views'); - -module.exports = class extends Generator { - constructor(args, options) { - super(args, options); - - this.fileType = options.fileType; - } - - prompting() { - const prompts = [ - { - message: "What's the name of the component you're documenting? Use snake_case, please.", - name: 'name', - type: 'input', - store: true, - }, - ]; - - if (this.fileType === 'demo') { - prompts.push({ - message: `What's the name of the directory this demo should go in? (Within ${DOCUMENTATION_PAGE_PATH}). Use snake_case, please.`, - name: 'folderName', - type: 'input', - store: true, - default: (answers) => answers.name, - }); - - prompts.push({ - message: 'What would you like to name this demo? Use snake_case, please.', - name: 'demoName', - type: 'input', - store: true, - }); - } - - return this.prompt(prompts).then((answers) => { - this.config = answers; - }); - } - - writing() { - const config = this.config; - - const writeDocumentationPage = () => { - const componentExampleName = utils.makeComponentName(config.name, false); - const componentExamplePrefix = utils.lowerCaseFirstLetter(componentExampleName); - const fileName = config.name; - - const path = DOCUMENTATION_PAGE_PATH; - - const vars = (config.documentationVars = { - componentExampleName, - componentExamplePrefix, - fileName, - }); - - const documentationPagePath = (config.documentationPagePath = `${path}/${config.name}/${config.name}_example.js`); - - this.fs.copyTpl( - this.templatePath('documentation_page.js'), - this.destinationPath(documentationPagePath), - vars - ); - }; - - const writeDocumentationPageDemo = (fileName, folderName) => { - const componentExampleName = utils.makeComponentName(fileName, false); - const componentExamplePrefix = utils.lowerCaseFirstLetter(componentExampleName); - const componentName = utils.makeComponentName(config.name); - - const path = DOCUMENTATION_PAGE_PATH; - - const vars = (config.documentationVars = { - componentExampleName, - componentExamplePrefix, - componentName, - fileName, - }); - - const documentationPageDemoPath = (config.documentationPageDemoPath = `${path}/${folderName}/${fileName}.js`); - - this.fs.copyTpl( - this.templatePath('documentation_page_demo.js'), - this.destinationPath(documentationPageDemoPath), - vars - ); - }; - - const writeSandbox = () => { - const fileName = config.name; - const componentExampleName = utils.makeComponentName(fileName, false); - - const path = DOCUMENTATION_PAGE_PATH; - - const vars = (config.documentationVars = { - componentExampleName, - fileName, - }); - - const sandboxPath = (config.documentationPageDemoPath = `${path}/${config.name}/${fileName}`); - - this.fs.copyTpl( - this.templatePath('documentation_sandbox.html'), - this.destinationPath(`${sandboxPath}_sandbox.html`) - ); - - this.fs.copyTpl( - this.templatePath('documentation_sandbox.js'), - this.destinationPath(`${sandboxPath}_sandbox.js`), - vars - ); - }; - - switch (this.fileType) { - case 'documentation': - writeDocumentationPage(); - writeDocumentationPageDemo(config.name, config.name); - break; - - case 'demo': - writeDocumentationPageDemo(config.demoName, config.folderName); - break; - - case 'sandbox': - writeSandbox(); - break; - } - } - - end() { - const showImportDemoSnippet = () => { - const { - componentExampleName, - componentExamplePrefix, - fileName, - } = this.config.documentationVars; - - this.log(chalk.white('\n// Import demo into example.')); - this.log( - `${chalk.magenta('import')} ${componentExampleName} from ${chalk.cyan( - `'./${fileName}'` - )};\n` + - `${chalk.magenta('const')} ${componentExamplePrefix}Source = require(${chalk.cyan( - `'!!raw-loader!./${fileName}'` - )});\n` + - `${chalk.magenta( - 'const' - )} ${componentExamplePrefix}Html = renderToHtml(${componentExampleName});` - ); - - this.log(chalk.white('\n// Render demo.')); - this.log( - `\n` + - ` \n` + - ` Description needed: how to use the ${componentExampleName} component.\n` + - ` \n` + - `\n` + - ` \n` + - ` <${componentExampleName} />\n` + - ` \n` + - `\n` - ); - }; - - const showImportRouteSnippet = (suffix, appendToRoute) => { - const { componentExampleName, fileName } = this.config.documentationVars; - - this.log(chalk.white('\n// Import example into routes.js.')); - this.log( - `${chalk.magenta('import')} ${componentExampleName}${suffix}\n` + - ` ${chalk.magenta('from')} ${chalk.cyan( - `'../../views/${fileName}/${fileName}_${suffix.toLowerCase()}'` - )};` - ); - - this.log(chalk.white('\n// Import route definition into routes.js.')); - this.log( - `{\n` + - ` name: ${chalk.cyan(`'${componentExampleName}${appendToRoute ? suffix : ''}'`)},\n` + - ` component: ${componentExampleName}${suffix},\n` + - ` hasReact: ${chalk.magenta('true')},\n` + - `}` - ); - }; - - this.log('------------------------------------------------'); - this.log(chalk.bold('Import snippets:')); - - switch (this.fileType) { - case 'documentation': - showImportRouteSnippet('Example'); - break; - - case 'demo': - showImportDemoSnippet(); - break; - - case 'sandbox': - showImportRouteSnippet('Sandbox', true); - break; - } - this.log('------------------------------------------------'); - } -}; diff --git a/packages/kbn-ui-framework/generator-kui/documentation/templates/documentation_page.js b/packages/kbn-ui-framework/generator-kui/documentation/templates/documentation_page.js deleted file mode 100644 index df45099bb9c647..00000000000000 --- a/packages/kbn-ui-framework/generator-kui/documentation/templates/documentation_page.js +++ /dev/null @@ -1,41 +0,0 @@ -/* eslint-disable import/no-duplicates */ - -import React from 'react'; - -import { renderToHtml } from '../../services'; - -import { - GuideCode, - GuideDemo, - GuidePage, - GuideSection, - GuideSectionTypes, - GuideText, -} from '../../components'; - -import <%= componentExampleName %> from './<%= fileName %>'; -import <%= componentExamplePrefix %>Source from '!!raw-loader!./<%= fileName %>'; // eslint-disable-line import/default -const <%= componentExamplePrefix %>Html = renderToHtml(<%= componentExampleName %>); - -export default props => ( - - Source, - }, { - type: GuideSectionTypes.HTML, - code: <%= componentExamplePrefix %>Html, - }]} - > - - Description needed: how to use the <%= componentExampleName %> component. - - - - <<%= componentExampleName %> /> - - - -); diff --git a/packages/kbn-ui-framework/generator-kui/documentation/templates/documentation_page_demo.js b/packages/kbn-ui-framework/generator-kui/documentation/templates/documentation_page_demo.js deleted file mode 100644 index 645f194bb3c7b4..00000000000000 --- a/packages/kbn-ui-framework/generator-kui/documentation/templates/documentation_page_demo.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react'; - -import { - <%= componentName %>, -} from '../../../../components'; - -export default () => ( - <<%= componentName %>> - - > -); diff --git a/packages/kbn-ui-framework/generator-kui/documentation/templates/documentation_sandbox.html b/packages/kbn-ui-framework/generator-kui/documentation/templates/documentation_sandbox.html deleted file mode 100644 index 2515d47beb72f9..00000000000000 --- a/packages/kbn-ui-framework/generator-kui/documentation/templates/documentation_sandbox.html +++ /dev/null @@ -1 +0,0 @@ -

Do whatever you want here!

diff --git a/packages/kbn-ui-framework/generator-kui/documentation/templates/documentation_sandbox.js b/packages/kbn-ui-framework/generator-kui/documentation/templates/documentation_sandbox.js deleted file mode 100644 index 6dd661601b891d..00000000000000 --- a/packages/kbn-ui-framework/generator-kui/documentation/templates/documentation_sandbox.js +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; - -import { - GuideDemo, - GuideSandbox, - GuideSandboxCodeToggle, - GuideSectionTypes, -} from '../../components'; - -import html from './<%= fileName %>_sandbox.html'; - -export default props => ( - - - - - -); diff --git a/packages/kbn-ui-framework/generator-kui/utils.js b/packages/kbn-ui-framework/generator-kui/utils.js deleted file mode 100644 index 0f7b910451767e..00000000000000 --- a/packages/kbn-ui-framework/generator-kui/utils.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -function makeComponentName(str, usePrefix = true) { - const words = str.split('_'); - - const componentName = words - .map(function (word) { - return upperCaseFirstLetter(word); - }) - .join(''); - - return `${usePrefix ? 'Kui' : ''}${componentName}`; -} - -function lowerCaseFirstLetter(str) { - return str.replace(/\w\S*/g, function (txt) { - return txt.charAt(0).toLowerCase() + txt.substr(1); - }); -} - -function upperCaseFirstLetter(str) { - return str.replace(/\w\S*/g, function (txt) { - return txt.charAt(0).toUpperCase() + txt.substr(1); - }); -} - -function addDirectoryToPath(path, dirName, shouldMakeDirectory) { - if (shouldMakeDirectory) { - return path + '/' + dirName; - } - return path; -} - -module.exports = { - makeComponentName: makeComponentName, - lowerCaseFirstLetter: lowerCaseFirstLetter, - upperCaseFirstLetter: upperCaseFirstLetter, - addDirectoryToPath: addDirectoryToPath, -}; diff --git a/packages/kbn-ui-framework/package.json b/packages/kbn-ui-framework/package.json index 9e3adf3f61f81b..2b66f684b0c5d3 100644 --- a/packages/kbn-ui-framework/package.json +++ b/packages/kbn-ui-framework/package.json @@ -5,9 +5,7 @@ "scripts": { "build": "../../node_modules/.bin/grunt prodBuild", "docSiteStart": "../../node_modules/.bin/grunt docSiteStart", - "docSiteBuild": "../../node_modules/.bin/grunt docSiteBuild", - "createComponent": "../../node_modules/.bin/yo ./generator-kui/app/component.js", - "documentComponent": "../../node_modules/.bin/yo ./generator-kui/app/documentation.js" + "docSiteBuild": "../../node_modules/.bin/grunt docSiteBuild" }, "kibana": { "build": { diff --git a/rfcs/text/0013_saved_object_migrations.md b/rfcs/text/0013_saved_object_migrations.md index c5069625cb8a66..1a0967d110d06a 100644 --- a/rfcs/text/0013_saved_object_migrations.md +++ b/rfcs/text/0013_saved_object_migrations.md @@ -212,39 +212,68 @@ Note: If none of the aliases exists, this is a new Elasticsearch cluster and no migrations are necessary. Create the `.kibana_7.10.0_001` index with the following aliases: `.kibana_current` and `.kibana_7.10.0`. -2. If `.kibana_current` and `.kibana_7.10.0` both exists and are pointing to the same index this version's migration has already been completed. +2. If the source is a < v6.5 `.kibana` index or < 7.4 `.kibana_task_manager` + index prepare the legacy index for a migration: + 1. Mark the legacy index as read-only and wait for all in-flight operations to drain (requires https://github.com/elastic/elasticsearch/pull/58094). This prevents any further writes from outdated nodes. Assuming this API is similar to the existing `//_close` API, we expect to receive `"acknowledged" : true` and `"shards_acknowledged" : true`. If all shards don’t acknowledge within the timeout, retry the operation until it succeeds. + 2. Clone the legacy index into a new index which has writes enabled. Use a fixed index name i.e `.kibana_pre6.5.0_001` or `.kibana_task_manager_pre7.4.0_001`. `POST /.kibana/_clone/.kibana_pre6.5.0_001?wait_for_active_shards=all {"settings": {"index.blocks.write": false}}`. Ignore errors if the clone already exists. Ignore errors if the legacy source doesn't exist. + 3. Wait for the cloning to complete `GET /_cluster/health/.kibana_pre6.5.0_001?wait_for_status=green&timeout=60s` If cloning doesn’t complete within the 60s timeout, log a warning for visibility and poll again. + 4. Apply the `convertToAlias` script if defined `POST /.kibana_pre6.5.0_001/_update_by_query?conflicts=proceed {"script": {...}}`. The `convertToAlias` script will have to be idempotent, preferably setting `ctx.op="noop"` on subsequent runs to avoid unecessary writes. + 5. Delete the legacy index and replace it with an alias of the same name + ``` + POST /_aliases + { + "actions" : [ + { "add": { "index": ".kibana_pre6.5.0_001", "alias": ".kibana" } }, + { "remove_index": { "index": ".kibana" } } + ] + } + ```. + Unlike the delete index API, the `remove_index` action will fail if + provided with an _alias_. Ignore "The provided expression [.kibana] + matches an alias, specify the corresponding concrete indices instead." + or "index_not_found_exception" errors. These actions are applied + atomically so that other Kibana instances will always see either a + `.kibana` index or an alias, but never neither. + 6. Use the cloned `.kibana_pre6.5.0_001` as the source for the rest of the migration algorithm. +3. If `.kibana_current` and `.kibana_7.10.0` both exists and are pointing to the same index this version's migration has already been completed. 1. Because the same version can have plugins enabled at any point in time, perform the mappings update in step (6) and migrate outdated documents with step (7). 2. Skip to step (9) to start serving traffic. -3. Fail the migration if: +4. Fail the migration if: 1. `.kibana_current` is pointing to an index that belongs to a later version of Kibana .e.g. `.kibana_7.12.0_001` 2. (Only in 8.x) The source index contains documents that belong to an unknown Saved Object type (from a disabled plugin). Log an error explaining that the plugin that created these documents needs to be enabled again or that these objects should be deleted. See section (4.2.1.4). -4. Mark the source index as read-only and wait for all in-flight operations to drain (requires https://github.com/elastic/elasticsearch/pull/58094). This prevents any further writes from outdated nodes. Assuming this API is similar to the existing `//_close` API, we expect to receive `"acknowledged" : true` and `"shards_acknowledged" : true`. If all shards don’t acknowledge within the timeout, retry the operation until it succeeds. -5. Clone the source index into a new target index which has writes enabled. All nodes on the same version will use the same fixed index name e.g. `.kibana_7.10.0_001`. The `001` postfix isn't used by Kibana, but allows for re-indexing an index should this be required by an Elasticsearch upgrade. E.g. re-index `.kibana_7.10.0_001` into `.kibana_7.10.0_002` and point the `.kibana_7.10.0` alias to `.kibana_7.10.0_002`. +5. Mark the source index as read-only and wait for all in-flight operations to drain (requires https://github.com/elastic/elasticsearch/pull/58094). This prevents any further writes from outdated nodes. Assuming this API is similar to the existing `//_close` API, we expect to receive `"acknowledged" : true` and `"shards_acknowledged" : true`. If all shards don’t acknowledge within the timeout, retry the operation until it succeeds. +6. Clone the source index into a new target index which has writes enabled. All nodes on the same version will use the same fixed index name e.g. `.kibana_7.10.0_001`. The `001` postfix isn't used by Kibana, but allows for re-indexing an index should this be required by an Elasticsearch upgrade. E.g. re-index `.kibana_7.10.0_001` into `.kibana_7.10.0_002` and point the `.kibana_7.10.0` alias to `.kibana_7.10.0_002`. 1. `POST /.kibana_n/_clone/.kibana_7.10.0_001?wait_for_active_shards=all {"settings": {"index.blocks.write": false}}`. Ignore errors if the clone already exists. 2. Wait for the cloning to complete `GET /_cluster/health/.kibana_7.10.0_001?wait_for_status=green&timeout=60s` If cloning doesn’t complete within the 60s timeout, log a warning for visibility and poll again. -6. Update the mappings of the target index +7. Update the mappings of the target index 1. Retrieve the existing mappings including the `migrationMappingPropertyHashes` metadata. 2. Update the mappings with `PUT /.kibana_7.10.0_001/_mapping`. The API deeply merges any updates so this won't remove the mappings of any plugins that were enabled in a previous version but are now disabled. 3. Ensure that fields are correctly indexed using the target index's latest mappings `POST /.kibana_7.10.0_001/_update_by_query?conflicts=proceed`. In the future we could optimize this query by only targeting documents: 1. That belong to a known saved object type. 2. Which don't have outdated migrationVersion numbers since these will be transformed anyway. 3. That belong to a type whose mappings were changed by comparing the `migrationMappingPropertyHashes`. (Metadata, unlike the mappings isn't commutative, so there is a small chance that the metadata hashes do not accurately reflect the latest mappings, however, this will just result in an less efficient query). -7. Transform documents by reading batches of outdated documents from the target index then transforming and updating them with optimistic concurrency control. +8. Transform documents by reading batches of outdated documents from the target index then transforming and updating them with optimistic concurrency control. 1. Ignore any version conflict errors. 2. If a document transform throws an exception, add the document to a failure list and continue trying to transform all other documents. If any failures occured, log the complete list of documents that failed to transform. Fail the migration. -8. Mark the migration as complete by doing a single atomic operation (requires https://github.com/elastic/elasticsearch/pull/58100) that: - 1. Checks that `.kibana-current` alias is still pointing to the source index - 2. Points the `.kibana-7.10.0` and `.kibana_current` aliases to the target index. - 3. If this fails with a "required alias [.kibana_current] does not exist" error fetch `.kibana_current` again: +9. Mark the migration as complete by doing a single atomic operation (requires https://github.com/elastic/elasticsearch/pull/58100) that: + 3. Checks that `.kibana_current` alias is still pointing to the source index + 4. Points the `.kibana_7.10.0` and `.kibana_current` aliases to the target index. + 5. If this fails with a "required alias [.kibana_current] does not exist" error fetch `.kibana_current` again: 1. If `.kibana_current` is _not_ pointing to our target index fail the migration. 2. If `.kibana_current` is pointing to our target index the migration has succeeded and we can proceed to step (9). -9. Start serving traffic. +10. Start serving traffic. + +This algorithm shares a weakness with our existing migration algorithm +(since v7.4). When the task manager index gets reindexed a reindex script is +applied. Because we delete the original task manager index there is no way to +rollback a failed task manager migration without a snapshot. Together with the limitations, this algorithm ensures that migrations are idempotent. If two nodes are started simultaneously, both of them will start -transforming documents in that version's target index, but because migrations are idempotent, it doesn’t matter which node’s writes win. +transforming documents in that version's target index, but because migrations +are idempotent, it doesn’t matter which node’s writes win.
In the future, this algorithm could enable (2.6) "read-only functionality during the downtime window" but this is outside of the scope of this RFC. diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts index 6988a3211fa12d..48187fe4653922 100644 --- a/src/core/public/doc_links/doc_links_service.ts +++ b/src/core/public/doc_links/doc_links_service.ts @@ -37,6 +37,7 @@ export class DocLinksService { ELASTIC_WEBSITE_URL, links: { dashboard: { + guide: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/dashboard.html`, drilldowns: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/drilldowns.html`, drilldownsTriggerPicker: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/url-drilldown.html#trigger-picker`, urlDrilldownTemplateSyntax: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/url-drilldown.html#templating`, @@ -134,6 +135,8 @@ export class DocLinksService { visualize: { guide: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/visualize.html`, timelionDeprecation: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/dashboard.html#timelion-deprecation`, + lens: `${ELASTIC_WEBSITE_URL}what-is/kibana-lens`, + maps: `${ELASTIC_WEBSITE_URL}maps`, }, }, }); @@ -146,6 +149,7 @@ export interface DocLinksStart { readonly ELASTIC_WEBSITE_URL: string; readonly links: { readonly dashboard: { + readonly guide: string; readonly drilldowns: string; readonly drilldownsTriggerPicker: string; readonly urlDrilldownTemplateSyntax: string; diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index fd2d943cab9d29..781a50f849e241 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -460,6 +460,7 @@ export interface DocLinksStart { // (undocumented) readonly links: { readonly dashboard: { + readonly guide: string; readonly drilldowns: string; readonly drilldownsTriggerPicker: string; readonly urlDrilldownTemplateSyntax: string; diff --git a/src/dev/build/tasks/os_packages/docker_generator/run.ts b/src/dev/build/tasks/os_packages/docker_generator/run.ts index 19487efe1366c9..8679cce9b11fcd 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/run.ts +++ b/src/dev/build/tasks/os_packages/docker_generator/run.ts @@ -40,7 +40,7 @@ export async function runDockerGenerator( ubi: boolean = false ) { // UBI var config - const baseOSImage = ubi ? 'docker.elastic.co/ubi8/ubi-minimal:latest' : 'centos:8'; + const baseOSImage = ubi ? 'docker.elastic.co/ubi8/ubi-minimal:8.2' : 'centos:8'; const ubiVersionTag = 'ubi8'; const ubiImageFlavor = ubi ? `-${ubiVersionTag}` : ''; diff --git a/src/plugins/apm_oss/README.asciidoc b/src/plugins/apm_oss/README.asciidoc new file mode 100644 index 00000000000000..c3c060a99ee272 --- /dev/null +++ b/src/plugins/apm_oss/README.asciidoc @@ -0,0 +1,5 @@ +# APM OSS plugin + +OSS plugin for APM. Includes index configuration and tutorial resources. + +See <<../../x-pack/plugins/apm/readme.md,the X-Pack APM plugin README>> for information about the main APM plugin. diff --git a/src/plugins/dashboard/public/application/actions/add_to_library_action.test.tsx b/src/plugins/dashboard/public/application/actions/add_to_library_action.test.tsx index 3f7d05e8692c2a..feb30b248c066f 100644 --- a/src/plugins/dashboard/public/application/actions/add_to_library_action.test.tsx +++ b/src/plugins/dashboard/public/application/actions/add_to_library_action.test.tsx @@ -35,7 +35,7 @@ import { coreMock } from '../../../../../core/public/mocks'; import { CoreStart } from 'kibana/public'; import { AddToLibraryAction } from '.'; import { embeddablePluginMock } from 'src/plugins/embeddable/public/mocks'; -import { ViewMode } from '../../../../embeddable/public'; +import { ErrorEmbeddable, ViewMode } from '../../../../embeddable/public'; const { setup, doStart } = embeddablePluginMock.createInstance(); setup.registerEmbeddableFactory( @@ -86,6 +86,16 @@ beforeEach(async () => { } }); +test('Add to library is incompatible with Error Embeddables', async () => { + const action = new AddToLibraryAction({ toasts: coreStart.notifications.toasts }); + const errorEmbeddable = new ErrorEmbeddable( + 'Wow what an awful error', + { id: ' 404' }, + embeddable.getRoot() as IContainer + ); + expect(await action.isCompatible({ embeddable: errorEmbeddable })).toBe(false); +}); + test('Add to library is compatible when embeddable on dashboard has value type input', async () => { const action = new AddToLibraryAction({ toasts: coreStart.notifications.toasts }); embeddable.updateInput(await embeddable.getInputAsValueType()); @@ -124,19 +134,15 @@ test('Add to library is not compatible when embeddable is not in a dashboard con expect(await action.isCompatible({ embeddable: orphanContactCard })).toBe(false); }); -test('Add to library replaces embeddableId but retains panel count', async () => { +test('Add to library replaces embeddableId and retains panel count', async () => { const dashboard = embeddable.getRoot() as IContainer; const originalPanelCount = Object.keys(dashboard.getInput().panels).length; - const originalPanelKeySet = new Set(Object.keys(dashboard.getInput().panels)); + const action = new AddToLibraryAction({ toasts: coreStart.notifications.toasts }); await action.execute({ embeddable }); expect(Object.keys(container.getInput().panels).length).toEqual(originalPanelCount); - - const newPanelId = Object.keys(container.getInput().panels).find( - (key) => !originalPanelKeySet.has(key) - ); - expect(newPanelId).toBeDefined(); - const newPanel = container.getInput().panels[newPanelId!]; + expect(Object.keys(container.getInput().panels)).toContain(embeddable.id); + const newPanel = container.getInput().panels[embeddable.id!]; expect(newPanel.type).toEqual(embeddable.type); }); @@ -152,15 +158,10 @@ test('Add to library returns reference type input', async () => { mockedByReferenceInput: { savedObjectId: 'testSavedObjectId', id: embeddable.id }, mockedByValueInput: { attributes: complicatedAttributes, id: embeddable.id } as EmbeddableInput, }); - const dashboard = embeddable.getRoot() as IContainer; - const originalPanelKeySet = new Set(Object.keys(dashboard.getInput().panels)); const action = new AddToLibraryAction({ toasts: coreStart.notifications.toasts }); await action.execute({ embeddable }); - const newPanelId = Object.keys(container.getInput().panels).find( - (key) => !originalPanelKeySet.has(key) - ); - expect(newPanelId).toBeDefined(); - const newPanel = container.getInput().panels[newPanelId!]; + expect(Object.keys(container.getInput().panels)).toContain(embeddable.id); + const newPanel = container.getInput().panels[embeddable.id!]; expect(newPanel.type).toEqual(embeddable.type); expect(newPanel.explicitInput.attributes).toBeUndefined(); expect(newPanel.explicitInput.savedObjectId).toBe('testSavedObjectId'); diff --git a/src/plugins/dashboard/public/application/actions/add_to_library_action.tsx b/src/plugins/dashboard/public/application/actions/add_to_library_action.tsx index d89c38f297e8fc..179e5d522a2b34 100644 --- a/src/plugins/dashboard/public/application/actions/add_to_library_action.tsx +++ b/src/plugins/dashboard/public/application/actions/add_to_library_action.tsx @@ -26,6 +26,7 @@ import { PanelNotFoundError, EmbeddableInput, isReferenceOrValueEmbeddable, + isErrorEmbeddable, } from '../../../../embeddable/public'; import { NotificationsStart } from '../../../../../core/public'; import { DashboardPanelState, DASHBOARD_CONTAINER_TYPE, DashboardContainer } from '..'; @@ -61,7 +62,8 @@ export class AddToLibraryAction implements ActionByType { } }); +test('Clone is incompatible with Error Embeddables', async () => { + const action = new ClonePanelAction(coreStart); + const errorEmbeddable = new ErrorEmbeddable( + 'Wow what an awful error', + { id: ' 404' }, + embeddable.getRoot() as IContainer + ); + expect(await action.isCompatible({ embeddable: errorEmbeddable })).toBe(false); +}); + test('Clone adds a new embeddable', async () => { const dashboard = embeddable.getRoot() as IContainer; const originalPanelCount = Object.keys(dashboard.getInput().panels).length; @@ -98,7 +108,12 @@ test('Clone adds a new embeddable', async () => { ); expect(newPanelId).toBeDefined(); const newPanel = container.getInput().panels[newPanelId!]; - expect(newPanel.type).toEqual(embeddable.type); + expect(newPanel.type).toEqual('placeholder'); + // let the placeholder load + await dashboard.untilEmbeddableLoaded(newPanelId!); + // now wait for the full embeddable to replace it + const loadedPanel = await dashboard.untilEmbeddableLoaded(newPanelId!); + expect(loadedPanel.type).toEqual(embeddable.type); }); test('Clones an embeddable without a saved object ID', async () => { diff --git a/src/plugins/dashboard/public/application/actions/clone_panel_action.tsx b/src/plugins/dashboard/public/application/actions/clone_panel_action.tsx index dc5887ee0e6440..2d98d419689c19 100644 --- a/src/plugins/dashboard/public/application/actions/clone_panel_action.tsx +++ b/src/plugins/dashboard/public/application/actions/clone_panel_action.tsx @@ -28,6 +28,7 @@ import { PanelNotFoundError, EmbeddableInput, SavedObjectEmbeddableInput, + isErrorEmbeddable, } from '../../../../embeddable/public'; import { placePanelBeside, @@ -66,7 +67,8 @@ export class ClonePanelAction implements ActionByType public async isCompatible({ embeddable }: ClonePanelActionContext) { return Boolean( - embeddable.getInput()?.viewMode !== ViewMode.VIEW && + !isErrorEmbeddable(embeddable) && + embeddable.getInput()?.viewMode !== ViewMode.VIEW && embeddable.getRoot() && embeddable.getRoot().isContainer && embeddable.getRoot().type === DASHBOARD_CONTAINER_TYPE diff --git a/src/plugins/dashboard/public/application/actions/library_notification_action.test.tsx b/src/plugins/dashboard/public/application/actions/library_notification_action.test.tsx index 996649677e6c95..f45d64cdc0ab81 100644 --- a/src/plugins/dashboard/public/application/actions/library_notification_action.test.tsx +++ b/src/plugins/dashboard/public/application/actions/library_notification_action.test.tsx @@ -30,7 +30,7 @@ import { coreMock } from '../../../../../core/public/mocks'; import { CoreStart } from 'kibana/public'; import { LibraryNotificationAction, UnlinkFromLibraryAction } from '.'; import { embeddablePluginMock } from 'src/plugins/embeddable/public/mocks'; -import { ViewMode } from '../../../../embeddable/public'; +import { ErrorEmbeddable, IContainer, ViewMode } from '../../../../embeddable/public'; const { setup, doStart } = embeddablePluginMock.createInstance(); setup.registerEmbeddableFactory( @@ -87,6 +87,16 @@ beforeEach(async () => { embeddable.updateInput({ viewMode: ViewMode.EDIT }); }); +test('Notification is incompatible with Error Embeddables', async () => { + const action = new LibraryNotificationAction(unlinkAction); + const errorEmbeddable = new ErrorEmbeddable( + 'Wow what an awful error', + { id: ' 404' }, + embeddable.getRoot() as IContainer + ); + expect(await action.isCompatible({ embeddable: errorEmbeddable })).toBe(false); +}); + test('Notification is shown when embeddable on dashboard has reference type input', async () => { const action = new LibraryNotificationAction(unlinkAction); embeddable.updateInput(await embeddable.getInputAsRefType()); diff --git a/src/plugins/dashboard/public/application/actions/library_notification_action.tsx b/src/plugins/dashboard/public/application/actions/library_notification_action.tsx index 6a0b71d8250be0..d6e75a3bb132b3 100644 --- a/src/plugins/dashboard/public/application/actions/library_notification_action.tsx +++ b/src/plugins/dashboard/public/application/actions/library_notification_action.tsx @@ -19,7 +19,12 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; -import { IEmbeddable, ViewMode, isReferenceOrValueEmbeddable } from '../../embeddable_plugin'; +import { + IEmbeddable, + ViewMode, + isReferenceOrValueEmbeddable, + isErrorEmbeddable, +} from '../../embeddable_plugin'; import { ActionByType, IncompatibleActionError } from '../../ui_actions_plugin'; import { reactToUiComponent } from '../../../../kibana_react/public'; import { UnlinkFromLibraryAction } from '.'; @@ -79,6 +84,7 @@ export class LibraryNotificationAction implements ActionByType { return ( + !isErrorEmbeddable(embeddable) && embeddable.getRoot().isContainer && embeddable.getInput()?.viewMode !== ViewMode.VIEW && isReferenceOrValueEmbeddable(embeddable) && diff --git a/src/plugins/dashboard/public/application/actions/unlink_from_library_action.test.tsx b/src/plugins/dashboard/public/application/actions/unlink_from_library_action.test.tsx index 0f61a74cd7036d..f191be6f7baad3 100644 --- a/src/plugins/dashboard/public/application/actions/unlink_from_library_action.test.tsx +++ b/src/plugins/dashboard/public/application/actions/unlink_from_library_action.test.tsx @@ -30,7 +30,11 @@ import { coreMock } from '../../../../../core/public/mocks'; import { CoreStart } from 'kibana/public'; import { UnlinkFromLibraryAction } from '.'; import { embeddablePluginMock } from 'src/plugins/embeddable/public/mocks'; -import { ViewMode, SavedObjectEmbeddableInput } from '../../../../embeddable/public'; +import { + ViewMode, + SavedObjectEmbeddableInput, + ErrorEmbeddable, +} from '../../../../embeddable/public'; const { setup, doStart } = embeddablePluginMock.createInstance(); setup.registerEmbeddableFactory( @@ -80,6 +84,16 @@ beforeEach(async () => { embeddable.updateInput({ viewMode: ViewMode.EDIT }); }); +test('Unlink is incompatible with Error Embeddables', async () => { + const action = new UnlinkFromLibraryAction({ toasts: coreStart.notifications.toasts }); + const errorEmbeddable = new ErrorEmbeddable( + 'Wow what an awful error', + { id: ' 404' }, + embeddable.getRoot() as IContainer + ); + expect(await action.isCompatible({ embeddable: errorEmbeddable })).toBe(false); +}); + test('Unlink is compatible when embeddable on dashboard has reference type input', async () => { const action = new UnlinkFromLibraryAction({ toasts: coreStart.notifications.toasts }); embeddable.updateInput(await embeddable.getInputAsRefType()); @@ -118,19 +132,14 @@ test('Unlink is not compatible when embeddable is not in a dashboard container', expect(await action.isCompatible({ embeddable: orphanContactCard })).toBe(false); }); -test('Unlink replaces embeddableId but retains panel count', async () => { +test('Unlink replaces embeddableId and retains panel count', async () => { const dashboard = embeddable.getRoot() as IContainer; const originalPanelCount = Object.keys(dashboard.getInput().panels).length; - const originalPanelKeySet = new Set(Object.keys(dashboard.getInput().panels)); const action = new UnlinkFromLibraryAction({ toasts: coreStart.notifications.toasts }); await action.execute({ embeddable }); expect(Object.keys(container.getInput().panels).length).toEqual(originalPanelCount); - - const newPanelId = Object.keys(container.getInput().panels).find( - (key) => !originalPanelKeySet.has(key) - ); - expect(newPanelId).toBeDefined(); - const newPanel = container.getInput().panels[newPanelId!]; + expect(Object.keys(container.getInput().panels)).toContain(embeddable.id); + const newPanel = container.getInput().panels[embeddable.id!]; expect(newPanel.type).toEqual(embeddable.type); }); @@ -150,15 +159,10 @@ test('Unlink unwraps all attributes from savedObject', async () => { mockedByReferenceInput: { savedObjectId: 'testSavedObjectId', id: embeddable.id }, mockedByValueInput: { attributes: complicatedAttributes, id: embeddable.id }, }); - const dashboard = embeddable.getRoot() as IContainer; - const originalPanelKeySet = new Set(Object.keys(dashboard.getInput().panels)); const action = new UnlinkFromLibraryAction({ toasts: coreStart.notifications.toasts }); await action.execute({ embeddable }); - const newPanelId = Object.keys(container.getInput().panels).find( - (key) => !originalPanelKeySet.has(key) - ); - expect(newPanelId).toBeDefined(); - const newPanel = container.getInput().panels[newPanelId!]; + expect(Object.keys(container.getInput().panels)).toContain(embeddable.id); + const newPanel = container.getInput().panels[embeddable.id!]; expect(newPanel.type).toEqual(embeddable.type); expect(newPanel.explicitInput.attributes).toEqual(complicatedAttributes); }); diff --git a/src/plugins/dashboard/public/application/actions/unlink_from_library_action.tsx b/src/plugins/dashboard/public/application/actions/unlink_from_library_action.tsx index f5cf8b4e866a85..5e16145364712d 100644 --- a/src/plugins/dashboard/public/application/actions/unlink_from_library_action.tsx +++ b/src/plugins/dashboard/public/application/actions/unlink_from_library_action.tsx @@ -26,6 +26,7 @@ import { PanelNotFoundError, EmbeddableInput, isReferenceOrValueEmbeddable, + isErrorEmbeddable, } from '../../../../embeddable/public'; import { NotificationsStart } from '../../../../../core/public'; import { DashboardPanelState, DASHBOARD_CONTAINER_TYPE, DashboardContainer } from '..'; @@ -61,7 +62,8 @@ export class UnlinkFromLibraryAction implements ActionByType merge( ...newChildIds.map((childId) => - dashboardContainer!.getChild(childId).getOutput$() + dashboardContainer! + .getChild(childId) + .getOutput$() + .pipe(catchError(() => EMPTY)) ) ) ) diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx index 89aacf2a84029c..caa8321d7b8b23 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx @@ -27,6 +27,7 @@ import { ContactCardEmbeddableInput, ContactCardEmbeddable, ContactCardEmbeddableOutput, + EMPTY_EMBEDDABLE, } from '../../embeddable_plugin_test_samples'; import { embeddablePluginMock } from 'src/plugins/embeddable/public/mocks'; @@ -100,6 +101,48 @@ test('DashboardContainer.addNewEmbeddable', async () => { expect(embeddableInContainer.id).toBe(embeddable.id); }); +test('DashboardContainer.replacePanel', async (done) => { + const ID = '123'; + const initialInput = getSampleDashboardInput({ + panels: { + [ID]: getSampleDashboardPanel({ + explicitInput: { firstName: 'Sam', id: ID }, + type: CONTACT_CARD_EMBEDDABLE, + }), + }, + }); + + const container = new DashboardContainer(initialInput, options); + let counter = 0; + + const subscriptionHandler = jest.fn(({ panels }) => { + counter++; + expect(panels[ID]).toBeDefined(); + // It should be called exactly 2 times and exit the second time + switch (counter) { + case 1: + return expect(panels[ID].type).toBe(CONTACT_CARD_EMBEDDABLE); + + case 2: { + expect(panels[ID].type).toBe(EMPTY_EMBEDDABLE); + subscription.unsubscribe(); + done(); + } + + default: + throw Error('Called too many times!'); + } + }); + + const subscription = container.getInput$().subscribe(subscriptionHandler); + + // replace the panel now + container.replacePanel(container.getInput().panels[ID], { + type: EMPTY_EMBEDDABLE, + explicitInput: { id: ID }, + }); +}); + test('Container view mode change propagates to existing children', async () => { const initialInput = getSampleDashboardInput({ panels: { diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx index 757488185fe8e5..051a7ef8bfb929 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx @@ -154,42 +154,43 @@ export class DashboardContainer extends Container) => - this.replacePanel(placeholderPanelState, newPanelState) - ); + + // wait until the placeholder is ready, then replace it with new panel + // this is useful as sometimes panels can load faster than the placeholder one (i.e. by value embeddables) + this.untilEmbeddableLoaded(originalPanelState.explicitInput.id) + .then(() => newStateComplete) + .then((newPanelState: Partial) => + this.replacePanel(placeholderPanelState, newPanelState) + ); } public replacePanel( previousPanelState: DashboardPanelState, newPanelState: Partial ) { - // TODO: In the current infrastructure, embeddables in a container do not react properly to - // changes. Removing the existing embeddable, and adding a new one is a temporary workaround - // until the container logic is fixed. - - const finalPanels = { ...this.input.panels }; - delete finalPanels[previousPanelState.explicitInput.id]; - const newPanelId = newPanelState.explicitInput?.id ? newPanelState.explicitInput.id : uuid.v4(); - finalPanels[newPanelId] = { - ...previousPanelState, - ...newPanelState, - gridData: { - ...previousPanelState.gridData, - i: newPanelId, - }, - explicitInput: { - ...newPanelState.explicitInput, - id: newPanelId, + // Because the embeddable type can change, we have to operate at the container level here + return this.updateInput({ + panels: { + ...this.input.panels, + [previousPanelState.explicitInput.id]: { + ...previousPanelState, + ...newPanelState, + gridData: { + ...previousPanelState.gridData, + }, + explicitInput: { + ...newPanelState.explicitInput, + id: previousPanelState.explicitInput.id, + }, + }, }, - }; - this.updateInput({ - panels: finalPanels, lastReloadRequestTime: new Date().getTime(), }); } @@ -201,16 +202,15 @@ export class DashboardContainer extends Container(type: string, explicitInput: Partial, embeddableId?: string) { const idToReplace = embeddableId || explicitInput.id; if (idToReplace && this.input.panels[idToReplace]) { - this.replacePanel(this.input.panels[idToReplace], { + return this.replacePanel(this.input.panels[idToReplace], { type, explicitInput: { ...explicitInput, - id: uuid.v4(), + id: idToReplace, }, }); - } else { - this.addNewEmbeddable(type, explicitInput); } + return this.addNewEmbeddable(type, explicitInput); } public render(dom: HTMLElement) { diff --git a/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.tsx b/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.tsx index d4d8fd0a4374b9..03c92d91a80ccb 100644 --- a/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.tsx +++ b/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.tsx @@ -265,6 +265,7 @@ class DashboardGridUi extends React.Component {
{ @@ -272,6 +273,8 @@ class DashboardGridUi extends React.Component { }} > Promise; + ) => Promise; createAggConfigs: ( indexPattern: IndexPattern, configStates?: CreateAggConfigParams[], diff --git a/src/plugins/data/common/search/aggs/utils/time_column_meta.test.ts b/src/plugins/data/common/search/aggs/utils/time_column_meta.test.ts index e56d6227345547..8eb076f5b79065 100644 --- a/src/plugins/data/common/search/aggs/utils/time_column_meta.test.ts +++ b/src/plugins/data/common/search/aggs/utils/time_column_meta.test.ts @@ -91,6 +91,43 @@ describe('getDateMetaByDatatableColumn', () => { }); }); + it('throws if unable to resolve interval', async () => { + await expect( + getDateMetaByDatatableColumn(params)({ + id: 'test', + name: 'test', + meta: { + type: 'date', + source: 'esaggs', + sourceParams: { + type: BUCKET_TYPES.DATE_HISTOGRAM, + params: { + time_zone: 'UTC', + interval: 'auto', + }, + }, + }, + }) + ).rejects.toBeDefined(); + + await expect( + getDateMetaByDatatableColumn(params)({ + id: 'test', + name: 'test', + meta: { + type: 'date', + source: 'esaggs', + sourceParams: { + type: BUCKET_TYPES.DATE_HISTOGRAM, + params: { + time_zone: 'UTC', + }, + }, + }, + }) + ).rejects.toBeDefined(); + }); + it('returns resolved auto interval', async () => { expect( await getDateMetaByDatatableColumn(params)({ @@ -106,8 +143,8 @@ describe('getDateMetaByDatatableColumn', () => { interval: 'auto', }, appliedTimeRange: { - from: 'now-5d', - to: 'now', + from: '2020-10-05T00:00:00.000Z', + to: '2020-10-10T00:00:00.000Z', }, }, }, diff --git a/src/plugins/data/common/search/aggs/utils/time_column_meta.ts b/src/plugins/data/common/search/aggs/utils/time_column_meta.ts index 1bea716c6a0490..7ed8cb79f63f47 100644 --- a/src/plugins/data/common/search/aggs/utils/time_column_meta.ts +++ b/src/plugins/data/common/search/aggs/utils/time_column_meta.ts @@ -38,11 +38,11 @@ export const getDateMetaByDatatableColumn = ({ getConfig, }: DateMetaByColumnDeps) => async ( column: DatatableColumn -): Promise => { +): Promise => { if (column.meta.source !== 'esaggs') return; if (column.meta.sourceParams?.type !== BUCKET_TYPES.DATE_HISTOGRAM) return; const params = column.meta.sourceParams.params as AggParamsDateHistogram; - const appliedTimeRange = column.meta.sourceParams.appliedTimeRange as TimeRange; + const appliedTimeRange = column.meta.sourceParams.appliedTimeRange as TimeRange | undefined; const tz = inferTimeZone( params, @@ -52,9 +52,11 @@ export const getDateMetaByDatatableColumn = ({ ); const interval = - params.interval === 'auto' ? calculateAutoTimeExpression(appliedTimeRange) : params.interval; + params.interval === 'auto' && appliedTimeRange + ? calculateAutoTimeExpression(appliedTimeRange) + : params.interval; - if (!interval) { + if (!interval || interval === 'auto') { throw new Error('time interval could not be determined'); } diff --git a/src/plugins/data/public/search/expressions/esaggs.ts b/src/plugins/data/public/search/expressions/esaggs.ts index dba77d398c8b67..3932484801fa81 100644 --- a/src/plugins/data/public/search/expressions/esaggs.ts +++ b/src/plugins/data/public/search/expressions/esaggs.ts @@ -267,6 +267,8 @@ export const esaggs = (): EsaggsExpressionFunctionDefinition => ({ searchSource.setField('index', indexPattern); searchSource.setField('size', 0); + const resolvedTimeRange = input?.timeRange && calculateBounds(input.timeRange); + const response = await handleCourierRequest({ searchSource, aggs, @@ -303,7 +305,10 @@ export const esaggs = (): EsaggsExpressionFunctionDefinition => ({ input?.timeRange && args.timeFields && args.timeFields.includes(column.aggConfig.params.field?.name) - ? { from: input.timeRange.from, to: input.timeRange.to } + ? { + from: resolvedTimeRange?.min?.toISOString(), + to: resolvedTimeRange?.max?.toISOString(), + } : undefined, ...column.aggConfig.serialize(), }, diff --git a/src/plugins/embeddable/public/lib/containers/container.ts b/src/plugins/embeddable/public/lib/containers/container.ts index 9f701f021162a1..4dede8bf5d752f 100644 --- a/src/plugins/embeddable/public/lib/containers/container.ts +++ b/src/plugins/embeddable/public/lib/containers/container.ts @@ -19,6 +19,7 @@ import uuid from 'uuid'; import { merge, Subscription } from 'rxjs'; +import { startWith, pairwise } from 'rxjs/operators'; import { Embeddable, EmbeddableInput, @@ -55,7 +56,12 @@ export abstract class Container< parent?: Container ) { super(input, output, parent); - this.subscription = this.getInput$().subscribe(() => this.maybeUpdateChildren()); + this.subscription = this.getInput$() + // At each update event, get both the previous and current state + .pipe(startWith(input), pairwise()) + .subscribe(([{ panels: prevPanels }, { panels: currentPanels }]) => { + this.maybeUpdateChildren(currentPanels, prevPanels); + }); } public updateInputForChild( @@ -329,16 +335,30 @@ export abstract class Container< return embeddable; } - private maybeUpdateChildren() { - const allIds = Object.keys({ ...this.input.panels, ...this.output.embeddableLoaded }); + private panelHasChanged(currentPanel: PanelState, prevPanel: PanelState) { + if (currentPanel.type !== prevPanel.type) { + return true; + } + } + + private maybeUpdateChildren( + currentPanels: TContainerInput['panels'], + prevPanels: TContainerInput['panels'] + ) { + const allIds = Object.keys({ ...currentPanels, ...this.output.embeddableLoaded }); allIds.forEach((id) => { - if (this.input.panels[id] !== undefined && this.output.embeddableLoaded[id] === undefined) { - this.onPanelAdded(this.input.panels[id]); - } else if ( - this.input.panels[id] === undefined && - this.output.embeddableLoaded[id] !== undefined - ) { - this.onPanelRemoved(id); + if (currentPanels[id] !== undefined && this.output.embeddableLoaded[id] === undefined) { + return this.onPanelAdded(currentPanels[id]); + } + if (currentPanels[id] === undefined && this.output.embeddableLoaded[id] !== undefined) { + return this.onPanelRemoved(id); + } + // In case of type change, remove and add a panel with the same id + if (currentPanels[id] && prevPanels[id]) { + if (this.panelHasChanged(currentPanels[id], prevPanels[id])) { + this.onPanelRemoved(id); + this.onPanelAdded(currentPanels[id]); + } } }); } diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx index c7afc157c14523..31df5c5085f8ba 100644 --- a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx @@ -43,6 +43,7 @@ export abstract class Embeddable< public readonly isContainer: boolean = false; public abstract readonly type: string; public readonly id: string; + public fatalError?: Error; protected output: TEmbeddableOutput; protected input: TEmbeddableInput; @@ -88,9 +89,12 @@ export abstract class Embeddable< map(({ title }) => title || ''), distinctUntilChanged() ) - .subscribe((title) => { - this.renderComplete.setTitle(title); - }); + .subscribe( + (title) => { + this.renderComplete.setTitle(title); + }, + () => {} + ); } public getIsContainer(): this is IContainer { @@ -193,6 +197,11 @@ export abstract class Embeddable< } } + protected onFatalError(e: Error) { + this.fatalError = e; + this.output$.error(e); + } + private onResetInput(newInput: TEmbeddableInput) { if (!isEqual(this.input, newInput)) { const oldLastReloadRequestTime = this.input.lastReloadRequestTime; diff --git a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx index cdbe7af98a4f40..34d971cbb717a6 100644 --- a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx @@ -30,7 +30,7 @@ export const ERROR_EMBEDDABLE_TYPE = 'error'; export function isErrorEmbeddable( embeddable: TEmbeddable | ErrorEmbeddable ): embeddable is ErrorEmbeddable { - return (embeddable as ErrorEmbeddable).error !== undefined; + return Boolean(embeddable.fatalError || (embeddable as ErrorEmbeddable).error !== undefined); } export class ErrorEmbeddable extends Embeddable { diff --git a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts index 3843950c164c96..5a73df2e138613 100644 --- a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts +++ b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts @@ -85,6 +85,11 @@ export interface IEmbeddable< */ enhancements?: object; + /** + * If this embeddable has encountered a fatal error, that error will be stored here + **/ + fatalError?: Error; + /** * A functional representation of the isContainer variable, but helpful for typescript to * know the shape if this returns true diff --git a/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx b/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx index 1cd48e85469fd7..4a1fd22894e7e9 100644 --- a/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx +++ b/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx @@ -50,7 +50,7 @@ import { EditPanelAction } from '../actions'; import { CustomizePanelModal } from './panel_header/panel_actions/customize_title/customize_panel_modal'; import { EmbeddableStart } from '../../plugin'; import { EmbeddableErrorLabel } from './embeddable_error_label'; -import { EmbeddableStateTransfer } from '..'; +import { EmbeddableStateTransfer, ErrorEmbeddable } from '..'; const sortByOrderField = ( { order: orderA }: { order?: number }, @@ -85,6 +85,7 @@ interface State { notifications: Array>; loading?: boolean; error?: EmbeddableError; + errorEmbeddable?: ErrorEmbeddable; } interface PanelUniversalActions { @@ -199,6 +200,9 @@ export class EmbeddablePanel extends React.Component { if (this.parentSubscription) { this.parentSubscription.unsubscribe(); } + if (this.state.errorEmbeddable) { + this.state.errorEmbeddable.destroy(); + } this.props.embeddable.destroy(); } @@ -257,12 +261,21 @@ export class EmbeddablePanel extends React.Component { public componentDidMount() { if (this.embeddableRoot.current) { this.subscription.add( - this.props.embeddable.getOutput$().subscribe((output: EmbeddableOutput) => { - this.setState({ - error: output.error, - loading: output.loading, - }); - }) + this.props.embeddable.getOutput$().subscribe( + (output: EmbeddableOutput) => { + this.setState({ + error: output.error, + loading: output.loading, + }); + }, + (error) => { + if (this.embeddableRoot.current) { + const errorEmbeddable = new ErrorEmbeddable(error, { id: this.props.embeddable.id }); + errorEmbeddable.render(this.embeddableRoot.current); + this.setState({ errorEmbeddable }); + } + } + ) ); this.props.embeddable.render(this.embeddableRoot.current); } diff --git a/src/plugins/embeddable/public/public.api.md b/src/plugins/embeddable/public/public.api.md index 8f0f56c4e1a166..4406dded98547a 100644 --- a/src/plugins/embeddable/public/public.api.md +++ b/src/plugins/embeddable/public/public.api.md @@ -278,6 +278,8 @@ export abstract class Embeddable>; // (undocumented) getInput(): Readonly; @@ -298,6 +300,8 @@ export abstract class Embeddable { destroy(): void; enhancements?: object; + fatalError?: Error; getInput$(): Readonly>; getInput(): Readonly; getInspectorAdapters(): Adapters | undefined; diff --git a/src/plugins/expressions/public/public.api.md b/src/plugins/expressions/public/public.api.md index e6bff703aadcd3..773d61ebe2e28a 100644 --- a/src/plugins/expressions/public/public.api.md +++ b/src/plugins/expressions/public/public.api.md @@ -1057,7 +1057,7 @@ export interface Range { // Warning: (ae-missing-release-tag) "ReactExpressionRenderer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const ReactExpressionRenderer: ({ className, dataAttrs, padding, renderError, expression, onEvent, reload$, debounce, ...expressionLoaderOptions }: ReactExpressionRendererProps) => JSX.Element; +export const ReactExpressionRenderer: ({ className, dataAttrs, padding, renderError, expression, onEvent, onData$, reload$, debounce, ...expressionLoaderOptions }: ReactExpressionRendererProps) => JSX.Element; // Warning: (ae-missing-release-tag) "ReactExpressionRendererProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -1072,6 +1072,8 @@ export interface ReactExpressionRendererProps extends IExpressionLoaderParams { // (undocumented) expression: string | ExpressionAstExpression; // (undocumented) + onData$?: (data: TData, adapters?: TInspectorAdapters) => void; + // (undocumented) onEvent?: (event: ExpressionRendererEvent) => void; // (undocumented) padding?: 'xs' | 's' | 'm' | 'l' | 'xl'; diff --git a/src/plugins/expressions/public/react_expression_renderer.test.tsx b/src/plugins/expressions/public/react_expression_renderer.test.tsx index 052c2a9f6a24a1..e52d4d153882ff 100644 --- a/src/plugins/expressions/public/react_expression_renderer.test.tsx +++ b/src/plugins/expressions/public/react_expression_renderer.test.tsx @@ -195,6 +195,38 @@ describe('ExpressionRenderer', () => { expect(instance.find('[data-test-subj="custom-error"]')).toHaveLength(0); }); + it('should call onData$ prop on every data$ observable emission in loader', () => { + const dataSubject = new Subject(); + const data$ = dataSubject.asObservable().pipe(share()); + + const newData = {}; + const inspectData = {}; + const onData$ = jest.fn(); + + (ExpressionLoader as jest.Mock).mockImplementation(() => { + return { + render$: new Subject(), + data$, + loading$: new Subject(), + events$: new Subject(), + update: jest.fn(), + inspect: jest.fn(() => inspectData), + }; + }); + + mount(); + + expect(onData$).toHaveBeenCalledTimes(0); + + act(() => { + dataSubject.next(newData); + }); + + expect(onData$).toHaveBeenCalledTimes(1); + expect(onData$.mock.calls[0][0]).toBe(newData); + expect(onData$.mock.calls[0][1]).toBe(inspectData); + }); + it('should fire onEvent prop on every events$ observable emission in loader', () => { const dataSubject = new Subject(); const data$ = dataSubject.asObservable().pipe(share()); diff --git a/src/plugins/expressions/public/react_expression_renderer.tsx b/src/plugins/expressions/public/react_expression_renderer.tsx index fecebf36ab7e6a..894325c8b65f7d 100644 --- a/src/plugins/expressions/public/react_expression_renderer.tsx +++ b/src/plugins/expressions/public/react_expression_renderer.tsx @@ -41,6 +41,7 @@ export interface ReactExpressionRendererProps extends IExpressionLoaderParams { ) => React.ReactElement | React.ReactElement[]; padding?: 'xs' | 's' | 'm' | 'l' | 'xl'; onEvent?: (event: ExpressionRendererEvent) => void; + onData$?: (data: TData, adapters?: TInspectorAdapters) => void; /** * An observable which can be used to re-run the expression without destroying the component */ @@ -71,6 +72,7 @@ export const ReactExpressionRenderer = ({ renderError, expression, onEvent, + onData$, reload$, debounce, ...expressionLoaderOptions @@ -135,6 +137,13 @@ export const ReactExpressionRenderer = ({ }) ); } + if (onData$) { + subs.push( + expressionLoaderRef.current.data$.subscribe((newData) => { + onData$(newData, expressionLoaderRef.current?.inspect()); + }) + ); + } subs.push( expressionLoaderRef.current.loading$.subscribe(() => { hasHandledErrorRef.current = false; diff --git a/src/plugins/input_control_vis/public/input_control_vis_type.ts b/src/plugins/input_control_vis/public/input_control_vis_type.ts index 782df67f5c58a4..6e33e18c1603b0 100644 --- a/src/plugins/input_control_vis/public/input_control_vis_type.ts +++ b/src/plugins/input_control_vis/public/input_control_vis_type.ts @@ -18,8 +18,7 @@ */ import { i18n } from '@kbn/i18n'; - -import { BaseVisTypeOptions } from 'src/plugins/visualizations/public'; +import { VisGroups, BaseVisTypeOptions } from '../../visualizations/public'; import { createInputControlVisController } from './vis_controller'; import { getControlsTab } from './components/editor/controls_tab'; import { OptionsTab } from './components/editor/options_tab'; @@ -37,8 +36,9 @@ export function createInputControlVisTypeDefinition( defaultMessage: 'Controls', }), icon: 'controlsHorizontal', + group: VisGroups.TOOLS, description: i18n.translate('inputControl.register.controlsDescription', { - defaultMessage: 'Create interactive controls for easy dashboard manipulation.', + defaultMessage: 'Add dropdown menus and range sliders to your dashboard.', }), stage: 'experimental', visualization: InputControlVisController, diff --git a/src/plugins/inspector/public/plugin.tsx b/src/plugins/inspector/public/plugin.tsx index f906dbcab80439..07ef7c8fbab0d4 100644 --- a/src/plugins/inspector/public/plugin.tsx +++ b/src/plugins/inspector/public/plugin.tsx @@ -70,7 +70,7 @@ export class InspectorPublicPlugin implements Plugin { public async setup(core: CoreSetup) { this.views = new InspectorViewRegistry(); - this.views.register(getDataViewDescription(core.uiSettings)); + this.views.register(getDataViewDescription()); this.views.register(getRequestsViewDescription()); return { @@ -101,7 +101,14 @@ export class InspectorPublicPlugin implements Plugin { } return core.overlays.openFlyout( - toMountPoint(), + toMountPoint( + + ), { 'data-test-subj': 'inspectorPanel', closeButtonAriaLabel: closeButtonLabel, diff --git a/src/plugins/inspector/public/ui/__snapshots__/inspector_panel.test.tsx.snap b/src/plugins/inspector/public/ui/__snapshots__/inspector_panel.test.tsx.snap index 709c0bfe69f0bd..7fb00fe8d40c41 100644 --- a/src/plugins/inspector/public/ui/__snapshots__/inspector_panel.test.tsx.snap +++ b/src/plugins/inspector/public/ui/__snapshots__/inspector_panel.test.tsx.snap @@ -10,6 +10,11 @@ exports[`InspectorPanel should render as expected 1`] = ` }, } } + dependencies={ + Object { + "uiSettings": Object {}, + } + } intl={ Object { "defaultFormats": Object {}, @@ -135,216 +140,228 @@ exports[`InspectorPanel should render as expected 1`] = ` ] } > - -
- -
- -
- -

- Inspector -

-
-
-
- -
+ Inspector + + +
+
+ - + - - - + } + } + views={ + Array [ + Object { + "component": [Function], + "order": 200, + "title": "View 1", + }, + Object { + "component": [Function], + "order": 100, + "shouldShow": [Function], + "title": "Foo View", + }, + Object { + "component": [Function], + "order": 200, + "shouldShow": [Function], + "title": "Never", + }, + ] } - closePopover={[Function]} - display="inlineBlock" - hasArrow={true} - id="inspectorViewChooser" - isOpen={false} - ownFocus={true} - panelPaddingSize="none" - repositionOnScroll={true} > - + + + } + closePopover={[Function]} + display="inlineBlock" + hasArrow={true} + id="inspectorViewChooser" + isOpen={false} + ownFocus={true} + panelPaddingSize="none" + repositionOnScroll={true} > -
- - - + + + +
-
- - - -
- -
- - - - -
+ + +
+ + + + + +
- -

- View 1 -

-
+ } + > + +

+ View 1 +

+
+
+
- -
+
+ `; diff --git a/src/plugins/inspector/public/ui/inspector_panel.scss b/src/plugins/inspector/public/ui/inspector_panel.scss index ff0b491e1222b9..2a6cfed66e4ff8 100644 --- a/src/plugins/inspector/public/ui/inspector_panel.scss +++ b/src/plugins/inspector/public/ui/inspector_panel.scss @@ -1,11 +1,15 @@ .insInspectorPanel__flyoutBody { - // TODO: EUI to allow for custom classNames to inner elements - // Or supply this as default - > div { + .euiFlyoutBody__overflowContent { + height: 100%; display: flex; + flex-wrap: nowrap; flex-direction: column; - > div { + >div { + flex-grow: 0; + } + + .insRequestCodeViewer { flex-grow: 1; } } diff --git a/src/plugins/inspector/public/ui/inspector_panel.test.tsx b/src/plugins/inspector/public/ui/inspector_panel.test.tsx index 23f698c23793b1..67e197abe7134e 100644 --- a/src/plugins/inspector/public/ui/inspector_panel.test.tsx +++ b/src/plugins/inspector/public/ui/inspector_panel.test.tsx @@ -22,10 +22,12 @@ import { mountWithIntl } from 'test_utils/enzyme_helpers'; import { InspectorPanel } from './inspector_panel'; import { InspectorViewDescription } from '../types'; import { Adapters } from '../../common'; +import type { IUiSettingsClient } from 'kibana/public'; describe('InspectorPanel', () => { let adapters: Adapters; let views: InspectorViewDescription[]; + const uiSettings: IUiSettingsClient = {} as IUiSettingsClient; beforeEach(() => { adapters = { @@ -62,12 +64,16 @@ describe('InspectorPanel', () => { }); it('should render as expected', () => { - const component = mountWithIntl(); + const component = mountWithIntl( + + ); expect(component).toMatchSnapshot(); }); it('should not allow updating adapters', () => { - const component = mountWithIntl(); + const component = mountWithIntl( + + ); adapters.notAllowed = {}; expect(() => component.setProps({ adapters })).toThrow(); }); diff --git a/src/plugins/inspector/public/ui/inspector_panel.tsx b/src/plugins/inspector/public/ui/inspector_panel.tsx index 37a51257112d63..dbad202953b0b5 100644 --- a/src/plugins/inspector/public/ui/inspector_panel.tsx +++ b/src/plugins/inspector/public/ui/inspector_panel.tsx @@ -19,12 +19,21 @@ import './inspector_panel.scss'; import { i18n } from '@kbn/i18n'; -import React, { Component } from 'react'; +import React, { Component, Suspense } from 'react'; import PropTypes from 'prop-types'; -import { EuiFlexGroup, EuiFlexItem, EuiFlyoutHeader, EuiTitle, EuiFlyoutBody } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiFlyoutHeader, + EuiTitle, + EuiFlyoutBody, + EuiLoadingSpinner, +} from '@elastic/eui'; +import { IUiSettingsClient } from 'kibana/public'; import { InspectorViewDescription } from '../types'; import { Adapters } from '../../common'; import { InspectorViewChooser } from './inspector_view_chooser'; +import { KibanaContextProvider } from '../../../kibana_react/public'; function hasAdaptersChanged(oldAdapters: Adapters, newAdapters: Adapters) { return ( @@ -41,6 +50,9 @@ interface InspectorPanelProps { adapters: Adapters; title?: string; views: InspectorViewDescription[]; + dependencies: { + uiSettings: IUiSettingsClient; + }; } interface InspectorPanelState { @@ -95,19 +107,21 @@ export class InspectorPanel extends Component + }> + + ); } render() { - const { views, title } = this.props; + const { views, title, dependencies } = this.props; const { selectedView } = this.state; return ( - + @@ -127,7 +141,7 @@ export class InspectorPanel extends Component {this.renderSelectedPanel()} - + ); } } diff --git a/src/plugins/inspector/public/views/data/components/__snapshots__/data_view.test.tsx.snap b/src/plugins/inspector/public/views/data/components/__snapshots__/data_view.test.tsx.snap index 2632afff2f63be..3bd3bb6531cc7f 100644 --- a/src/plugins/inspector/public/views/data/components/__snapshots__/data_view.test.tsx.snap +++ b/src/plugins/inspector/public/views/data/components/__snapshots__/data_view.test.tsx.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Inspector Data View component should render empty state 1`] = ` - - + `; exports[`Inspector Data View component should render loading state 1`] = ` - + loading + } intl={ Object { @@ -431,204 +439,9 @@ exports[`Inspector Data View component should render loading state 1`] = ` "timeZone": null, } } - title="Test Data" > - - -
- -
- -
- - - - - - - - - -
- - -
-

- - Gathering data - -

-
-
-
- -
- -
- - - +
+ loading +
+ `; diff --git a/src/plugins/inspector/public/views/data/components/data_view.test.tsx b/src/plugins/inspector/public/views/data/components/data_view.test.tsx index bd78bca42c4796..6a7f878ef807e8 100644 --- a/src/plugins/inspector/public/views/data/components/data_view.test.tsx +++ b/src/plugins/inspector/public/views/data/components/data_view.test.tsx @@ -17,11 +17,10 @@ * under the License. */ -import React from 'react'; +import React, { Suspense } from 'react'; import { getDataViewDescription } from '../index'; import { DataAdapter } from '../../../../common/adapters/data'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; -import { IUiSettingsClient } from '../../../../../../core/public'; jest.mock('../lib/export_csv', () => ({ exportAsCsv: jest.fn(), @@ -31,9 +30,7 @@ describe('Inspector Data View', () => { let DataView: any; beforeEach(() => { - const uiSettings = {} as IUiSettingsClient; - - DataView = getDataViewDescription(uiSettings); + DataView = getDataViewDescription(); }); it('should only show if data adapter is present', () => { @@ -51,7 +48,12 @@ describe('Inspector Data View', () => { }); it('should render loading state', () => { - const component = mountWithIntl(); // eslint-disable-line react/jsx-pascal-case + const DataViewComponent = DataView.component; + const component = mountWithIntl( + loading
}> + + + ); expect(component).toMatchSnapshot(); }); diff --git a/src/plugins/inspector/public/views/data/components/data_view.tsx b/src/plugins/inspector/public/views/data/components/data_view.tsx index 1a2b6f9922d2d0..100fa7787321ca 100644 --- a/src/plugins/inspector/public/views/data/components/data_view.tsx +++ b/src/plugins/inspector/public/views/data/components/data_view.tsx @@ -38,6 +38,7 @@ import { TabularCallback, } from '../../../../common/adapters/data/types'; import { IUiSettingsClient } from '../../../../../../core/public'; +import { withKibana, KibanaReactContextValue } from '../../../../../kibana_react/public'; interface DataViewComponentState { tabularData: TabularData | null; @@ -47,20 +48,23 @@ interface DataViewComponentState { } interface DataViewComponentProps extends InspectorViewProps { - uiSettings: IUiSettingsClient; + kibana: KibanaReactContextValue<{ uiSettings: IUiSettingsClient }>; } -export class DataViewComponent extends Component { +class DataViewComponent extends Component { static propTypes = { - uiSettings: PropTypes.object.isRequired, adapters: PropTypes.object.isRequired, title: PropTypes.string.isRequired, + kibana: PropTypes.object, }; state = {} as DataViewComponentState; _isMounted = false; - static getDerivedStateFromProps(nextProps: InspectorViewProps, state: DataViewComponentState) { + static getDerivedStateFromProps( + nextProps: DataViewComponentProps, + state: DataViewComponentState + ) { if (state && nextProps.adapters === state.adapters) { return null; } @@ -172,8 +176,12 @@ export class DataViewComponent extends Component ); } } + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export default withKibana(DataViewComponent); diff --git a/src/plugins/inspector/public/views/data/index.tsx b/src/plugins/inspector/public/views/data/index.ts similarity index 72% rename from src/plugins/inspector/public/views/data/index.tsx rename to src/plugins/inspector/public/views/data/index.ts index b02e02bbe6b6b6..d201ad89022be9 100644 --- a/src/plugins/inspector/public/views/data/index.tsx +++ b/src/plugins/inspector/public/views/data/index.ts @@ -16,17 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -import React from 'react'; +import { lazy } from 'react'; import { i18n } from '@kbn/i18n'; -import { DataViewComponent } from './components/data_view'; -import { InspectorViewDescription, InspectorViewProps } from '../../types'; +import { InspectorViewDescription } from '../../types'; import { Adapters } from '../../../common'; -import { IUiSettingsClient } from '../../../../../core/public'; -export const getDataViewDescription = ( - uiSettings: IUiSettingsClient -): InspectorViewDescription => ({ +const DataViewComponent = lazy(() => import('./components/data_view')); + +export const getDataViewDescription = (): InspectorViewDescription => ({ title: i18n.translate('inspector.data.dataTitle', { defaultMessage: 'Data', }), @@ -37,7 +35,5 @@ export const getDataViewDescription = ( shouldShow(adapters: Adapters) { return Boolean(adapters.data); }, - component: (props: InspectorViewProps) => ( - - ), + component: DataViewComponent, }); diff --git a/src/plugins/inspector/public/views/requests/components/details/req_code_viewer.tsx b/src/plugins/inspector/public/views/requests/components/details/req_code_viewer.tsx new file mode 100644 index 00000000000000..71499d46071c87 --- /dev/null +++ b/src/plugins/inspector/public/views/requests/components/details/req_code_viewer.tsx @@ -0,0 +1,82 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiFlexItem, EuiFlexGroup, EuiCopy, EuiButtonEmpty, EuiSpacer } from '@elastic/eui'; + +import { CodeEditor } from '../../../../../../kibana_react/public'; + +interface RequestCodeViewerProps { + json: string; +} + +const copyToClipboardLabel = i18n.translate('inspector.requests.copyToClipboardLabel', { + defaultMessage: 'Copy to clipboard', +}); + +/** + * @internal + */ +export const RequestCodeViewer = ({ json }: RequestCodeViewerProps) => ( + + + +
+ + {(copy) => ( + + {copyToClipboardLabel} + + )} + +
+
+ + {}} + options={{ + readOnly: true, + lineNumbers: 'off', + fontSize: 12, + minimap: { + enabled: false, + }, + scrollBeyondLastLine: false, + wordWrap: 'on', + wrappingIndent: 'indent', + automaticLayout: true, + }} + /> + +
+); diff --git a/src/plugins/inspector/public/views/requests/components/details/req_details_request.tsx b/src/plugins/inspector/public/views/requests/components/details/req_details_request.tsx index d7cb8f57456138..47ed226c24a5ce 100644 --- a/src/plugins/inspector/public/views/requests/components/details/req_details_request.tsx +++ b/src/plugins/inspector/public/views/requests/components/details/req_details_request.tsx @@ -19,9 +19,9 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { EuiCodeBlock } from '@elastic/eui'; import { Request } from '../../../../../common/adapters/request/types'; import { RequestDetailsProps } from '../types'; +import { RequestCodeViewer } from './req_code_viewer'; export class RequestDetailsRequest extends Component { static propTypes = { @@ -37,15 +37,6 @@ export class RequestDetailsRequest extends Component { return null; } - return ( - - {JSON.stringify(json, null, 2)} - - ); + return ; } } diff --git a/src/plugins/inspector/public/views/requests/components/details/req_details_response.tsx b/src/plugins/inspector/public/views/requests/components/details/req_details_response.tsx index 933495ff473961..5ad5cc0537adaa 100644 --- a/src/plugins/inspector/public/views/requests/components/details/req_details_response.tsx +++ b/src/plugins/inspector/public/views/requests/components/details/req_details_response.tsx @@ -19,9 +19,9 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { EuiCodeBlock } from '@elastic/eui'; import { Request } from '../../../../../common/adapters/request/types'; import { RequestDetailsProps } from '../types'; +import { RequestCodeViewer } from './req_code_viewer'; export class RequestDetailsResponse extends Component { static propTypes = { @@ -40,15 +40,6 @@ export class RequestDetailsResponse extends Component { return null; } - return ( - - {JSON.stringify(responseJSON, null, 2)} - - ); + return ; } } diff --git a/src/plugins/inspector/public/views/requests/components/requests_view.tsx b/src/plugins/inspector/public/views/requests/components/requests_view.tsx index 13575de0c5064f..7762689daf4e68 100644 --- a/src/plugins/inspector/public/views/requests/components/requests_view.tsx +++ b/src/plugins/inspector/public/views/requests/components/requests_view.tsx @@ -175,3 +175,7 @@ export class RequestsViewComponent extends Component import('./components/requests_view')); + export const getRequestsViewDescription = (): InspectorViewDescription => ({ title: i18n.translate('inspector.requests.requestsTitle', { defaultMessage: 'Requests', diff --git a/src/plugins/lens_oss/README.md b/src/plugins/lens_oss/README.md new file mode 100644 index 00000000000000..187da2497026e9 --- /dev/null +++ b/src/plugins/lens_oss/README.md @@ -0,0 +1,6 @@ +# lens_oss + +The lens_oss plugin registers the lens visualization on OSS. +It is registered as disabled. The x-pack plugin should unregister this. + +`visualizations.unregisterAlias('lensOss')` \ No newline at end of file diff --git a/src/plugins/lens_oss/common/constants.ts b/src/plugins/lens_oss/common/constants.ts new file mode 100644 index 00000000000000..ac92c9e1969936 --- /dev/null +++ b/src/plugins/lens_oss/common/constants.ts @@ -0,0 +1,22 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +export const APP_NAME = 'lens'; +export const PLUGIN_ID_OSS = 'lensOss'; +export const APP_PATH = '#/'; +export const APP_ICON = 'lensApp'; diff --git a/src/plugins/visualizations/public/wizard/type_selection/index.ts b/src/plugins/lens_oss/common/index.ts similarity index 94% rename from src/plugins/visualizations/public/wizard/type_selection/index.ts rename to src/plugins/lens_oss/common/index.ts index c4093b4dec3e83..fd1c2843d6b26a 100644 --- a/src/plugins/visualizations/public/wizard/type_selection/index.ts +++ b/src/plugins/lens_oss/common/index.ts @@ -17,4 +17,4 @@ * under the License. */ -export { TypeSelection } from './type_selection'; +export * from './constants'; diff --git a/src/plugins/lens_oss/config.ts b/src/plugins/lens_oss/config.ts new file mode 100644 index 00000000000000..6749bd83de39f9 --- /dev/null +++ b/src/plugins/lens_oss/config.ts @@ -0,0 +1,26 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; + +export const configSchema = schema.object({ + enabled: schema.boolean({ defaultValue: true }), +}); + +export type ConfigSchema = TypeOf; diff --git a/src/plugins/lens_oss/kibana.json b/src/plugins/lens_oss/kibana.json new file mode 100644 index 00000000000000..3e3d3585f37fb8 --- /dev/null +++ b/src/plugins/lens_oss/kibana.json @@ -0,0 +1,10 @@ +{ + "id": "lensOss", + "version": "kibana", + "ui": true, + "server": true, + "requiredPlugins": [ + "visualizations" + ], + "extraPublicDirs": ["common/constants"] +} diff --git a/src/plugins/lens_oss/public/index.ts b/src/plugins/lens_oss/public/index.ts new file mode 100644 index 00000000000000..f936052a37264b --- /dev/null +++ b/src/plugins/lens_oss/public/index.ts @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { LensOSSPlugin } from './plugin'; + +export const plugin = () => new LensOSSPlugin(); diff --git a/packages/kbn-ui-framework/generator-kui/app/component.js b/src/plugins/lens_oss/public/plugin.ts similarity index 53% rename from packages/kbn-ui-framework/generator-kui/app/component.js rename to src/plugins/lens_oss/public/plugin.ts index bcb561f6fa7295..15b815dab87c87 100644 --- a/packages/kbn-ui-framework/generator-kui/app/component.js +++ b/src/plugins/lens_oss/public/plugin.ts @@ -16,37 +16,27 @@ * specific language governing permissions and limitations * under the License. */ +import { DocLinksStart, CoreSetup } from 'src/core/public'; +import { VisualizationsSetup } from '../../visualizations/public'; +import { getLensAliasConfig } from './vis_type_alias'; -const Generator = require('yeoman-generator'); +export interface LensPluginSetupDependencies { + visualizations: VisualizationsSetup; +} -const componentGenerator = require.resolve('../component/index.js'); +export interface LensPluginStartDependencies { + docLinks: DocLinksStart; +} -module.exports = class extends Generator { - prompting() { - return this.prompt([ - { - message: 'What do you want to create?', - name: 'fileType', - type: 'list', - choices: [ - { - name: 'Stateless function', - value: 'function', - }, - { - name: 'Component class', - value: 'component', - }, - ], - }, - ]).then((answers) => { - this.config = answers; +export class LensOSSPlugin { + setup( + core: CoreSetup, + { visualizations }: LensPluginSetupDependencies + ) { + core.getStartServices().then(([coreStart]) => { + visualizations.registerAlias(getLensAliasConfig(coreStart.docLinks)); }); } - writing() { - this.composeWith(componentGenerator, { - fileType: this.config.fileType, - }); - } -}; + start() {} +} diff --git a/src/plugins/lens_oss/public/vis_type_alias.ts b/src/plugins/lens_oss/public/vis_type_alias.ts new file mode 100644 index 00000000000000..230209646deb55 --- /dev/null +++ b/src/plugins/lens_oss/public/vis_type_alias.ts @@ -0,0 +1,48 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { i18n } from '@kbn/i18n'; +import { VisTypeAlias } from 'src/plugins/visualizations/public'; +import { DocLinksStart } from 'src/core/public'; +import { APP_NAME, PLUGIN_ID_OSS, APP_PATH, APP_ICON } from '../common'; + +export const getLensAliasConfig = ({ links }: DocLinksStart): VisTypeAlias => ({ + aliasPath: APP_PATH, + aliasApp: APP_NAME, + name: PLUGIN_ID_OSS, + title: i18n.translate('lensOss.visTypeAlias.title', { + defaultMessage: 'Lens', + }), + description: i18n.translate('lensOss.visTypeAlias.description', { + defaultMessage: + 'Create visualizations with our drag-and-drop editor. Switch between visualization types at any time. Best for most visualizations.', + }), + icon: APP_ICON, + stage: 'production', + disabled: true, + note: i18n.translate('lensOss.visTypeAlias.note', { + defaultMessage: 'Recommended for most users.', + }), + promoTooltip: { + description: i18n.translate('lensOss.visTypeAlias.promoTooltip.description', { + defaultMessage: 'Try Lens for free with Elastic. Learn more.', + }), + link: `${links.visualize.lens}?blade=kibanaossvizwizard`, + }, +}); diff --git a/src/plugins/visualizations/public/wizard/type_selection/vis_type_icon.tsx b/src/plugins/lens_oss/server/index.ts similarity index 54% rename from src/plugins/visualizations/public/wizard/type_selection/vis_type_icon.tsx rename to src/plugins/lens_oss/server/index.ts index a9837313f29171..1a089a5382cc15 100644 --- a/src/plugins/visualizations/public/wizard/type_selection/vis_type_icon.tsx +++ b/src/plugins/lens_oss/server/index.ts @@ -17,25 +17,16 @@ * under the License. */ -import { EuiIcon, IconType } from '@elastic/eui'; -import React from 'react'; +import { PluginConfigDescriptor } from 'kibana/server'; +import { copyFromRoot } from '@kbn/config'; +import { configSchema, ConfigSchema } from '../config'; -interface VisTypeIconProps { - icon?: IconType; - image?: string; -} - -/** - * This renders the icon for a specific visualization type. - * This currently checks the following: - * - If image is set, use that as the `src` of an image - * - Otherwise use the icon as an EuiIcon or the 'empty' icon if that's not set - */ -export const VisTypeIcon = ({ icon, image }: VisTypeIconProps) => { - return ( - - {image && } - {!image && } - - ); +export const config: PluginConfigDescriptor = { + schema: configSchema, + deprecations: () => [copyFromRoot('xpack.lens.enabled', 'lens_oss.enabled')], }; + +export const plugin = () => ({ + setup() {}, + start() {}, +}); diff --git a/src/plugins/maps_oss/README.md b/src/plugins/maps_oss/README.md new file mode 100644 index 00000000000000..ed91de500fbfb0 --- /dev/null +++ b/src/plugins/maps_oss/README.md @@ -0,0 +1,6 @@ +# maps_oss + +The maps_oss plugin registers the maps visualization on OSS. +It is registered as disabled. The x-pack plugin should unregister this. + +`visualizations.unregisterAlias('mapsOss')` \ No newline at end of file diff --git a/src/plugins/maps_oss/common/constants.ts b/src/plugins/maps_oss/common/constants.ts new file mode 100644 index 00000000000000..b4063c68840b38 --- /dev/null +++ b/src/plugins/maps_oss/common/constants.ts @@ -0,0 +1,22 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +export const APP_NAME = 'maps'; +export const PLUGIN_ID_OSS = 'mapsOss'; +export const APP_PATH = '/map'; +export const APP_ICON = 'gisApp'; diff --git a/src/plugins/maps_oss/common/index.ts b/src/plugins/maps_oss/common/index.ts new file mode 100644 index 00000000000000..fd1c2843d6b26a --- /dev/null +++ b/src/plugins/maps_oss/common/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './constants'; diff --git a/src/plugins/maps_oss/config.ts b/src/plugins/maps_oss/config.ts new file mode 100644 index 00000000000000..6749bd83de39f9 --- /dev/null +++ b/src/plugins/maps_oss/config.ts @@ -0,0 +1,26 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; + +export const configSchema = schema.object({ + enabled: schema.boolean({ defaultValue: true }), +}); + +export type ConfigSchema = TypeOf; diff --git a/src/plugins/maps_oss/kibana.json b/src/plugins/maps_oss/kibana.json new file mode 100644 index 00000000000000..19770dcffaadd7 --- /dev/null +++ b/src/plugins/maps_oss/kibana.json @@ -0,0 +1,10 @@ +{ + "id": "mapsOss", + "version": "kibana", + "ui": true, + "server": true, + "requiredPlugins": [ + "visualizations" + ], + "extraPublicDirs": ["common/constants"] +} diff --git a/src/plugins/maps_oss/public/index.ts b/src/plugins/maps_oss/public/index.ts new file mode 100644 index 00000000000000..ec18ff1fde638a --- /dev/null +++ b/src/plugins/maps_oss/public/index.ts @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { MapsOSSPlugin } from './plugin'; + +export const plugin = () => new MapsOSSPlugin(); diff --git a/src/plugins/visualizations/public/wizard/type_selection/vis_help_text.tsx b/src/plugins/maps_oss/public/plugin.ts similarity index 53% rename from src/plugins/visualizations/public/wizard/type_selection/vis_help_text.tsx rename to src/plugins/maps_oss/public/plugin.ts index 8517919955f7cc..3369e0bf277065 100644 --- a/src/plugins/visualizations/public/wizard/type_selection/vis_help_text.tsx +++ b/src/plugins/maps_oss/public/plugin.ts @@ -17,34 +17,27 @@ * under the License. */ -import React from 'react'; +import { DocLinksStart, CoreSetup } from 'src/core/public'; +import { VisualizationsSetup } from '../../visualizations/public'; +import { getMapsAliasConfig } from './vis_type_alias'; -import { EuiSpacer, EuiText, EuiTitle } from '@elastic/eui'; +export interface MapsPluginSetupDependencies { + visualizations: VisualizationsSetup; +} -interface VisHelpTextProps { - name: string; - title: string; - description?: string; - highlightMsg?: string; +export interface MapsPluginStartDependencies { + docLinks: DocLinksStart; } -export const VisHelpText = ({ name, title, description, highlightMsg }: VisHelpTextProps) => { - return ( - - -

{title}

-
- -
- - {highlightMsg && ( -

- {highlightMsg} -

- )} -

{description}

-
-
-
- ); -}; +export class MapsOSSPlugin { + setup( + core: CoreSetup, + { visualizations }: MapsPluginSetupDependencies + ) { + core.getStartServices().then(([coreStart]) => { + visualizations.registerAlias(getMapsAliasConfig(coreStart.docLinks)); + }); + } + + start() {} +} diff --git a/src/plugins/maps_oss/public/vis_type_alias.ts b/src/plugins/maps_oss/public/vis_type_alias.ts new file mode 100644 index 00000000000000..14fdc06bc539f7 --- /dev/null +++ b/src/plugins/maps_oss/public/vis_type_alias.ts @@ -0,0 +1,44 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { i18n } from '@kbn/i18n'; +import { VisTypeAlias } from 'src/plugins/visualizations/public'; +import { DocLinksStart } from 'src/core/public'; +import { APP_NAME, PLUGIN_ID_OSS, APP_PATH, APP_ICON } from '../common'; + +export const getMapsAliasConfig = ({ links }: DocLinksStart): VisTypeAlias => ({ + aliasPath: APP_PATH, + aliasApp: APP_NAME, + name: PLUGIN_ID_OSS, + title: i18n.translate('mapsOss.visTypeAlias.title', { + defaultMessage: 'Maps', + }), + description: i18n.translate('mapsOss.visTypeAlias.description', { + defaultMessage: 'Plot and style your geo data in a multi layer map.', + }), + icon: APP_ICON, + stage: 'production', + disabled: true, + promoTooltip: { + description: i18n.translate('mapsOss.visTypeAlias.promoTooltip.description', { + defaultMessage: 'Try maps for free with Elastic. Learn more.', + }), + link: `${links.visualize.maps}?blade=kibanaossvizwizard`, + }, +}); diff --git a/src/plugins/maps_oss/server/index.ts b/src/plugins/maps_oss/server/index.ts new file mode 100644 index 00000000000000..defc3a09c25383 --- /dev/null +++ b/src/plugins/maps_oss/server/index.ts @@ -0,0 +1,32 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { PluginConfigDescriptor } from 'kibana/server'; +import { copyFromRoot } from '@kbn/config'; +import { configSchema, ConfigSchema } from '../config'; + +export const config: PluginConfigDescriptor = { + schema: configSchema, + deprecations: () => [copyFromRoot('xpack.maps.enabled', 'maps_oss.enabled')], +}; + +export const plugin = () => ({ + setup() {}, + start() {}, +}); diff --git a/src/plugins/region_map/config.ts b/src/plugins/region_map/config.ts index a721a76ca0a829..d60831563ed2b9 100644 --- a/src/plugins/region_map/config.ts +++ b/src/plugins/region_map/config.ts @@ -19,28 +19,29 @@ import { schema, TypeOf } from '@kbn/config-schema'; -export const configSchema = schema.object({ - includeElasticMapsService: schema.boolean({ defaultValue: true }), - layers: schema.arrayOf( +const layerConfigSchema = schema.object({ + url: schema.string(), + format: schema.object({ + type: schema.string({ defaultValue: 'geojson' }), + }), + meta: schema.object({ + feature_collection_path: schema.string({ defaultValue: 'data' }), + }), + attribution: schema.string(), + name: schema.string(), + fields: schema.arrayOf( schema.object({ - url: schema.string(), - format: schema.object({ - type: schema.string({ defaultValue: 'geojson' }), - }), - meta: schema.object({ - feature_collection_path: schema.string({ defaultValue: 'data' }), - }), - attribution: schema.string(), name: schema.string(), - fields: schema.arrayOf( - schema.object({ - name: schema.string(), - description: schema.string(), - }) - ), - }), - { defaultValue: [] } + description: schema.string(), + }) ), }); +export const configSchema = schema.object({ + includeElasticMapsService: schema.boolean({ defaultValue: true }), + layers: schema.arrayOf(layerConfigSchema, { defaultValue: [] }), +}); + +export type LayerConfig = TypeOf; + export type ConfigSchema = TypeOf; diff --git a/src/plugins/vis_type_markdown/public/markdown_vis.ts b/src/plugins/vis_type_markdown/public/markdown_vis.ts index 27ac038aee6fff..b6ec2cbd993b08 100644 --- a/src/plugins/vis_type_markdown/public/markdown_vis.ts +++ b/src/plugins/vis_type_markdown/public/markdown_vis.ts @@ -22,6 +22,7 @@ import { i18n } from '@kbn/i18n'; import { MarkdownOptions } from './markdown_options'; import { SettingsOptions } from './settings_options_lazy'; import { DefaultEditorSize } from '../../vis_default_editor/public'; +import { VisGroups } from '../../visualizations/public'; import { toExpressionAst } from './to_ast'; export const markdownVisDefinition = { @@ -29,8 +30,12 @@ export const markdownVisDefinition = { title: 'Markdown', isAccessible: true, icon: 'visText', + group: VisGroups.TOOLS, + titleInWizard: i18n.translate('visTypeMarkdown.markdownTitleInWizard', { + defaultMessage: 'Text', + }), description: i18n.translate('visTypeMarkdown.markdownDescription', { - defaultMessage: 'Create a document using markdown syntax', + defaultMessage: 'Add text and images to your dashboard.', }), toExpressionAst, visConfig: { diff --git a/src/plugins/vis_type_timeseries/public/metrics_type.ts b/src/plugins/vis_type_timeseries/public/metrics_type.ts index d6621870fef67e..682517ab1a9968 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_type.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_type.ts @@ -25,15 +25,16 @@ import { EditorController } from './application'; // @ts-ignore import { PANEL_TYPES } from '../common/panel_types'; import { VisEditor } from './application/components/vis_editor_lazy'; -import { VIS_EVENT_TO_TRIGGER } from '../../visualizations/public'; +import { VIS_EVENT_TO_TRIGGER, VisGroups } from '../../visualizations/public'; export const metricsVisDefinition = { name: 'metrics', title: i18n.translate('visTypeTimeseries.kbnVisTypes.metricsTitle', { defaultMessage: 'TSVB' }), description: i18n.translate('visTypeTimeseries.kbnVisTypes.metricsDescription', { - defaultMessage: 'Build time-series using a visual pipeline interface', + defaultMessage: 'Perform advanced analysis of your time series data.', }), icon: 'visVisualBuilder', + group: VisGroups.PROMOTED, visConfig: { defaults: { id: '61ca57f0-469d-11e7-af02-69e470af7417', diff --git a/src/plugins/vis_type_vega/public/vega_type.ts b/src/plugins/vis_type_vega/public/vega_type.ts index 17f35b75f00167..2211abb54aa93f 100644 --- a/src/plugins/vis_type_vega/public/vega_type.ts +++ b/src/plugins/vis_type_vega/public/vega_type.ts @@ -25,7 +25,7 @@ import { VegaVisualizationDependencies } from './plugin'; import { createVegaRequestHandler } from './vega_request_handler'; import { getDefaultSpec } from './default_spec'; import { createInspectorAdapters } from './vega_inspector'; -import { VIS_EVENT_TO_TRIGGER } from '../../visualizations/public'; +import { VIS_EVENT_TO_TRIGGER, VisGroups } from '../../visualizations/public'; import { toExpressionAst } from './to_ast'; import { VisParams } from './vega_fn'; import { getInfoMessage } from './components/experimental_map_vis_info'; @@ -41,10 +41,17 @@ export const createVegaTypeDefinition = ( title: 'Vega', getInfoMessage, description: i18n.translate('visTypeVega.type.vegaDescription', { - defaultMessage: 'Create custom visualizations using Vega and Vega-Lite', + defaultMessage: 'Use Vega to create new types of visualizations.', description: 'Vega and Vega-Lite are product names and should not be translated', }), + note: i18n.translate('visTypeVega.type.vegaNote', { + defaultMessage: 'Requires knowledge of Vega syntax.', + }), icon: 'visVega', + group: VisGroups.PROMOTED, + titleInWizard: i18n.translate('visTypeVega.type.vegaTitleInWizard', { + defaultMessage: 'Custom visualization', + }), visConfig: { defaults: { spec: getDefaultSpec() } }, editorConfig: { optionsTemplate: VegaVisEditorComponent, diff --git a/src/plugins/vis_type_vislib/public/gauge.ts b/src/plugins/vis_type_vislib/public/gauge.ts index 86e3b8793d618c..2b3c415087ee1e 100644 --- a/src/plugins/vis_type_vislib/public/gauge.ts +++ b/src/plugins/vis_type_vislib/public/gauge.ts @@ -61,8 +61,7 @@ export const gaugeVisTypeDefinition: BaseVisTypeOptions = { title: i18n.translate('visTypeVislib.gauge.gaugeTitle', { defaultMessage: 'Gauge' }), icon: 'visGauge', description: i18n.translate('visTypeVislib.gauge.gaugeDescription', { - defaultMessage: - "Gauges indicate the status of a metric. Use it to show how a metric's value relates to reference threshold values.", + defaultMessage: 'Gauges indicate the status of a metric.', }), toExpressionAst, visConfig: { diff --git a/src/plugins/visualizations/public/index.scss b/src/plugins/visualizations/public/index.scss index 2b61535f3e7f23..0202419cea2328 100644 --- a/src/plugins/visualizations/public/index.scss +++ b/src/plugins/visualizations/public/index.scss @@ -1,3 +1,2 @@ -@import 'wizard/index'; @import 'embeddable/index'; @import 'components/index'; diff --git a/src/plugins/visualizations/public/index.ts b/src/plugins/visualizations/public/index.ts index 7bd4466b23166b..d66a6f6113cad7 100644 --- a/src/plugins/visualizations/public/index.ts +++ b/src/plugins/visualizations/public/index.ts @@ -36,6 +36,7 @@ export { getSchemas as getVisSchemas } from './legacy/build_pipeline'; /** @public types */ export { VisualizationsSetup, VisualizationsStart }; +export { VisGroups } from './vis_types'; export type { VisTypeAlias, VisType, BaseVisTypeOptions, ReactVisTypeOptions } from './vis_types'; export { VisParams, SerializedVis, SerializedVisData, VisData } from './vis'; export type VisualizeEmbeddableFactoryContract = PublicContract; diff --git a/src/plugins/visualizations/public/mocks.ts b/src/plugins/visualizations/public/mocks.ts index f20e87dbd3b6a8..66399352bea7d9 100644 --- a/src/plugins/visualizations/public/mocks.ts +++ b/src/plugins/visualizations/public/mocks.ts @@ -41,6 +41,8 @@ const createStartContract = (): VisualizationsStart => ({ get: jest.fn(), all: jest.fn(), getAliases: jest.fn(), + getByGroup: jest.fn(), + unRegisterAlias: jest.fn(), savedVisualizationsLoader: { get: jest.fn(), } as any, diff --git a/src/plugins/visualizations/public/plugin.ts b/src/plugins/visualizations/public/plugin.ts index c1dbe39def64c8..29e31e92b971e2 100644 --- a/src/plugins/visualizations/public/plugin.ts +++ b/src/plugins/visualizations/public/plugin.ts @@ -49,6 +49,7 @@ import { setOverlays, setSavedSearchLoader, setEmbeddable, + setDocLinks, } from './services'; import { VISUALIZE_EMBEDDABLE_TYPE, @@ -172,6 +173,7 @@ export class VisualizationsPlugin setCapabilities(core.application.capabilities); setHttp(core.http); setSavedObjects(core.savedObjects); + setDocLinks(core.docLinks); setIndexPatterns(data.indexPatterns); setSearch(data.search); setFilterManager(data.query.filterManager); diff --git a/src/plugins/visualizations/public/services.ts b/src/plugins/visualizations/public/services.ts index 0761b8862e8e36..08537b4ac30810 100644 --- a/src/plugins/visualizations/public/services.ts +++ b/src/plugins/visualizations/public/services.ts @@ -26,6 +26,7 @@ import { IUiSettingsClient, OverlayStart, SavedObjectsStart, + DocLinksStart, } from '../../../core/public'; import { TypesStart } from './vis_types'; import { createGetterSetter } from '../../../plugins/kibana_utils/public'; @@ -60,6 +61,8 @@ export const [getTypes, setTypes] = createGetterSetter('Types'); export const [getI18n, setI18n] = createGetterSetter('I18n'); +export const [getDocLinks, setDocLinks] = createGetterSetter('DocLinks'); + export const [getFilterManager, setFilterManager] = createGetterSetter( 'FilterManager' ); diff --git a/src/plugins/visualizations/public/vis_types/base_vis_type.ts b/src/plugins/visualizations/public/vis_types/base_vis_type.ts index f2933de723a393..807582723172da 100644 --- a/src/plugins/visualizations/public/vis_types/base_vis_type.ts +++ b/src/plugins/visualizations/public/vis_types/base_vis_type.ts @@ -20,7 +20,7 @@ import { defaultsDeep } from 'lodash'; import { ISchemas } from 'src/plugins/vis_default_editor/public'; import { VisParams } from '../types'; -import { VisType, VisTypeOptions } from './types'; +import { VisType, VisTypeOptions, VisGroups } from './types'; interface CommonBaseVisTypeOptions extends Pick< @@ -41,7 +41,14 @@ interface CommonBaseVisTypeOptions >, Pick< Partial>, - 'editorConfig' | 'hidden' | 'stage' | 'useCustomNoDataScreen' | 'visConfig' + | 'editorConfig' + | 'hidden' + | 'stage' + | 'useCustomNoDataScreen' + | 'visConfig' + | 'group' + | 'titleInWizard' + | 'note' > { options?: Partial['options']>; } @@ -72,10 +79,13 @@ export class BaseVisType implements VisType public readonly name; public readonly title; public readonly description; + public readonly note; public readonly getSupportedTriggers; public readonly icon; public readonly image; public readonly stage; + public readonly group; + public readonly titleInWizard; public readonly options; public readonly visualization; public readonly visConfig; @@ -98,6 +108,7 @@ export class BaseVisType implements VisType this.name = opts.name; this.description = opts.description ?? ''; + this.note = opts.note ?? ''; this.getSupportedTriggers = opts.getSupportedTriggers; this.title = opts.title; this.icon = opts.icon; @@ -108,6 +119,8 @@ export class BaseVisType implements VisType this.editorConfig = defaultsDeep({}, opts.editorConfig, { collections: {} }); this.options = defaultsDeep({}, opts.options, defaultOptions); this.stage = opts.stage ?? 'production'; + this.group = opts.group ?? VisGroups.AGGBASED; + this.titleInWizard = opts.titleInWizard ?? ''; this.hidden = opts.hidden ?? false; this.requestHandler = opts.requestHandler ?? 'courier'; this.responseHandler = opts.responseHandler ?? 'none'; diff --git a/src/plugins/visualizations/public/vis_types/index.ts b/src/plugins/visualizations/public/vis_types/index.ts index a46b257c9905c1..a02ac82c8d1223 100644 --- a/src/plugins/visualizations/public/vis_types/index.ts +++ b/src/plugins/visualizations/public/vis_types/index.ts @@ -18,6 +18,7 @@ */ export * from './types_service'; +export { VisGroups } from './types'; export type { VisType } from './types'; export type { BaseVisTypeOptions } from './base_vis_type'; export type { ReactVisTypeOptions } from './react_vis_type'; diff --git a/src/plugins/visualizations/public/vis_types/types.ts b/src/plugins/visualizations/public/vis_types/types.ts index 7206e9612f1024..ee804e5677243c 100644 --- a/src/plugins/visualizations/public/vis_types/types.ts +++ b/src/plugins/visualizations/public/vis_types/types.ts @@ -33,21 +33,63 @@ export interface VisTypeOptions { hierarchicalData: boolean; } +export enum VisGroups { + PROMOTED = 'promoted', + TOOLS = 'tools', + AGGBASED = 'aggbased', +} + /** * A visualization type representing one specific type of "classical" * visualizations (i.e. not Lens visualizations). */ export interface VisType { + /** + * Visualization unique name + */ readonly name: string; + /** + * It is the displayed text on the wizard and the vis listing + */ readonly title: string; + /** + * If given, it will be diplayed on the wizard vis card as the main description. + */ readonly description?: string; + /** + * If given, it will be diplayed on the wizard vis card as a note in italic. + */ + readonly note: string; + /** + * If given, it will return the supported triggers for this vis. + */ readonly getSupportedTriggers?: () => Array; readonly isAccessible?: boolean; readonly requestHandler?: string | unknown; readonly responseHandler?: string | unknown; + /** + * It is the visualization icon, displayed on the wizard. + */ readonly icon?: IconType; + /** + * Except from an icon, an image can be passed + */ readonly image?: string; + /** + * Describes the visualization stage + */ readonly stage: 'experimental' | 'beta' | 'production'; + /** + * Describes the experience group that the visualization belongs. + * It can be on tools, aggregation based or promoted group. + */ + readonly group: VisGroups; + /** + * If given, it will be displayed on the wizard instead of the title. + * We use it because we want to differentiate the vis title from the + * way it is presented on the wizard + */ + readonly titleInWizard: string; readonly requiresSearch: boolean; readonly useCustomNoDataScreen: boolean; readonly hierarchicalData?: boolean | ((vis: { params: TVisParams }) => boolean); diff --git a/src/plugins/visualizations/public/vis_types/types_service.ts b/src/plugins/visualizations/public/vis_types/types_service.ts index 5d619064c240e9..27276eeb889238 100644 --- a/src/plugins/visualizations/public/vis_types/types_service.ts +++ b/src/plugins/visualizations/public/vis_types/types_service.ts @@ -20,7 +20,7 @@ import { visTypeAliasRegistry, VisTypeAlias } from './vis_type_alias_registry'; import { BaseVisType, BaseVisTypeOptions } from './base_vis_type'; import { ReactVisType, ReactVisTypeOptions } from './react_vis_type'; -import { VisType } from './types'; +import { VisType, VisGroups } from './types'; /** * Vis Types Service @@ -101,6 +101,21 @@ export class TypesService { * returns all registered aliases */ getAliases: visTypeAliasRegistry.get, + /** + * unregisters a visualization alias by its name + * alias is a visualization type without implementation, it just redirects somewhere in kibana + * @param {string} visTypeAliasName - visualization alias name + */ + unRegisterAlias: visTypeAliasRegistry.remove, + /** + * returns all visualizations of specific group + * @param {VisGroups} group - group type (aggbased | other | tools) + */ + getByGroup: (group: VisGroups) => { + return Object.values(this.types).filter((type) => { + return type.group === group; + }); + }, }; } diff --git a/src/plugins/visualizations/public/vis_types/vis_type_alias_registry.ts b/src/plugins/visualizations/public/vis_types/vis_type_alias_registry.ts index 9733e9fd685499..fc5dfd4e123fb7 100644 --- a/src/plugins/visualizations/public/vis_types/vis_type_alias_registry.ts +++ b/src/plugins/visualizations/public/vis_types/vis_type_alias_registry.ts @@ -43,9 +43,9 @@ export interface VisualizationsAppExtension { }) => VisualizationListItem; } -export interface VisTypeAliasPromotion { +export interface VisTypeAliasPromoTooltip { description: string; - buttonText: string; + link: string; } export interface VisTypeAlias { @@ -54,8 +54,11 @@ export interface VisTypeAlias { name: string; title: string; icon: string; - promotion?: VisTypeAliasPromotion; + promotion?: boolean; + promoTooltip?: VisTypeAliasPromoTooltip; description: string; + note?: string; + disabled?: boolean; getSupportedTriggers?: () => Array; stage: 'experimental' | 'beta' | 'production'; @@ -65,11 +68,13 @@ export interface VisTypeAlias { }; } -const registry: VisTypeAlias[] = []; +let registry: VisTypeAlias[] = []; +const discardOnRegister: string[] = []; interface VisTypeAliasRegistry { get: () => VisTypeAlias[]; add: (newVisTypeAlias: VisTypeAlias) => void; + remove: (visTypeAliasName: string) => void; } export const visTypeAliasRegistry: VisTypeAliasRegistry = { @@ -78,6 +83,22 @@ export const visTypeAliasRegistry: VisTypeAliasRegistry = { if (registry.find((visTypeAlias) => visTypeAlias.name === newVisTypeAlias.name)) { throw new Error(`${newVisTypeAlias.name} already registered`); } - registry.push(newVisTypeAlias); + // if it exists on discardOnRegister array then we don't allow it to be registered + const isToBeDiscarded = discardOnRegister.some( + (aliasName) => aliasName === newVisTypeAlias.name + ); + if (!isToBeDiscarded) { + registry.push(newVisTypeAlias); + } + }, + remove: (visTypeAliasName) => { + const isAliasPresent = registry.find((visTypeAlias) => visTypeAlias.name === visTypeAliasName); + // in case the alias has not registered yet we store it on an array, in order to not allow it to + // be registered in case of a race condition + if (!isAliasPresent) { + discardOnRegister.push(visTypeAliasName); + } else { + registry = registry.filter((visTypeAlias) => visTypeAlias.name !== visTypeAliasName); + } }, }; diff --git a/src/plugins/visualizations/public/wizard/__snapshots__/new_vis_modal.test.tsx.snap b/src/plugins/visualizations/public/wizard/__snapshots__/new_vis_modal.test.tsx.snap deleted file mode 100644 index 2089289b372a2a..00000000000000 --- a/src/plugins/visualizations/public/wizard/__snapshots__/new_vis_modal.test.tsx.snap +++ /dev/null @@ -1,2141 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`NewVisModal filter for visualization types should render as expected 1`] = ` - - - -
-
- -
-
-
- New Visualization -
-
-
-
-
-
-
-
-
- -
- - -
-
- -
-
-
-
-
- - 3 types found - -
    -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
-
-
-
-
-

- Select a visualization type -

-
-
-

- Start creating your visualization by selecting a type for that visualization. -

-

- - promotion description - -

- -
-
-
-
-
-
-
-
- } - > - - -
-
- - - - - -
- - -
- -
- - New Visualization - -
-
-
-
-
- -
- -
- -
- -
- - -
-
- - - - -
- - - - - -
-
- - - - - -
-
-
-
-
-
-
-
- -
- - - - 3 types found - - - - -
    -
  • - - Vis alias with promotion - - } - onBlur={[Function]} - onClick={[Function]} - onFocus={[Function]} - onMouseEnter={[Function]} - onMouseLeave={[Function]} - > - - -
  • -
  • - - Vis with alias Url - - } - onBlur={[Function]} - onClick={[Function]} - onFocus={[Function]} - onMouseEnter={[Function]} - onMouseLeave={[Function]} - > - - -
  • -
  • - - Vis with search - - } - onBlur={[Function]} - onClick={[Function]} - onFocus={[Function]} - onMouseEnter={[Function]} - onMouseLeave={[Function]} - > - - -
  • -
  • - - Vis Type 1 - - } - onBlur={[Function]} - onClick={[Function]} - onFocus={[Function]} - onMouseEnter={[Function]} - onMouseLeave={[Function]} - > - - -
  • -
-
-
-
-
-
-
-
- -
- -

- - Select a visualization type - -

-
- -
- - - -
-

- - Start creating your visualization by selecting a type for that visualization. - -

-

- - promotion description - -

- - - - - -
-
-
-
- -
- -
- -
-
-
- - - - - -`; - -exports[`NewVisModal should render as expected 1`] = ` - - - -
-
- -
-
-
- New Visualization -
-
-
-
-
-
-
-
-
- -
- - -
-
-
-
-
- -
    -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
-
-
-
-
-

- Select a visualization type -

-
-
-

- Start creating your visualization by selecting a type for that visualization. -

-

- - promotion description - -

- -
-
-
-
-
-
-
-
- } - > - - -
-
- - - - - -
- - -
- -
- - New Visualization - -
-
-
-
-
- -
- -
- -
- -
- - -
-
- - - - -
- - - - - -
-
-
-
-
-
-
-
- -
- - - - -
    -
  • - - Vis alias with promotion - - } - onBlur={[Function]} - onClick={[Function]} - onFocus={[Function]} - onMouseEnter={[Function]} - onMouseLeave={[Function]} - > - - -
  • -
  • - - Vis Type 1 - - } - onBlur={[Function]} - onClick={[Function]} - onFocus={[Function]} - onMouseEnter={[Function]} - onMouseLeave={[Function]} - > - - -
  • -
  • - - Vis with alias Url - - } - onBlur={[Function]} - onClick={[Function]} - onFocus={[Function]} - onMouseEnter={[Function]} - onMouseLeave={[Function]} - > - - -
  • -
  • - - Vis with search - - } - onBlur={[Function]} - onClick={[Function]} - onFocus={[Function]} - onMouseEnter={[Function]} - onMouseLeave={[Function]} - > - - -
  • -
-
-
-
-
-
-
-
- -
- -

- - Select a visualization type - -

-
- -
- - - -
-

- - Start creating your visualization by selecting a type for that visualization. - -

-

- - promotion description - -

- - - - - -
-
-
-
- -
- -
- -
-
-
- - - - - -`; diff --git a/src/plugins/visualizations/public/wizard/_index.scss b/src/plugins/visualizations/public/wizard/_index.scss deleted file mode 100644 index a10b4b1b347b7e..00000000000000 --- a/src/plugins/visualizations/public/wizard/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import 'dialog'; diff --git a/src/plugins/visualizations/public/wizard/agg_based_selection/agg_based_selection.test.tsx b/src/plugins/visualizations/public/wizard/agg_based_selection/agg_based_selection.test.tsx new file mode 100644 index 00000000000000..3cbe6a0b604c65 --- /dev/null +++ b/src/plugins/visualizations/public/wizard/agg_based_selection/agg_based_selection.test.tsx @@ -0,0 +1,122 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { mountWithIntl } from 'test_utils/enzyme_helpers'; +import { TypesStart, VisType, VisGroups } from '../../vis_types'; +import { AggBasedSelection } from './agg_based_selection'; + +describe('AggBasedSelection', () => { + const defaultVisTypeParams = { + hidden: false, + visualization: class Controller { + public render = jest.fn(); + public destroy = jest.fn(); + }, + requiresSearch: false, + requestHandler: 'none', + responseHandler: 'none', + }; + const _visTypes = [ + { + name: 'vis1', + title: 'Vis Type 1', + stage: 'production', + group: VisGroups.PROMOTED, + ...defaultVisTypeParams, + }, + { + name: 'vis2', + title: 'Vis Type 2', + group: VisGroups.AGGBASED, + stage: 'production', + ...defaultVisTypeParams, + }, + { + name: 'vis3', + title: 'Vis Type 3', + stage: 'production', + group: VisGroups.AGGBASED, + }, + { + name: 'visWithSearch', + title: 'Vis with search', + group: VisGroups.AGGBASED, + stage: 'production', + ...defaultVisTypeParams, + }, + ] as VisType[]; + + const visTypes: TypesStart = { + get(id: string): VisType { + return _visTypes.find((vis) => vis.name === id) as VisType; + }, + all: () => { + return (_visTypes as unknown) as VisType[]; + }, + getAliases: () => [], + unRegisterAlias: () => [], + getByGroup: (group: VisGroups) => { + return _visTypes.filter((type) => { + return type.group === group; + }) as VisType[]; + }, + }; + + beforeAll(() => { + Object.defineProperty(window, 'location', { + value: { + assign: jest.fn(), + }, + }); + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should call the toggleGroups if the user clicks the goBack link', () => { + const toggleGroups = jest.fn(); + const wrapper = mountWithIntl( + + ); + const aggBasedGroupCard = wrapper.find('[data-test-subj="goBackLink"]').at(0); + aggBasedGroupCard.simulate('click'); + expect(toggleGroups).toHaveBeenCalled(); + }); + + describe('filter for visualization types', () => { + it('should render as expected', () => { + const wrapper = mountWithIntl( + + ); + const searchBox = wrapper.find('input[data-test-subj="filterVisType"]'); + searchBox.simulate('change', { target: { value: 'with' } }); + expect(wrapper.find('[data-test-subj="visType-visWithSearch"]').exists()).toBe(true); + }); + }); +}); diff --git a/src/plugins/visualizations/public/wizard/agg_based_selection/agg_based_selection.tsx b/src/plugins/visualizations/public/wizard/agg_based_selection/agg_based_selection.tsx new file mode 100644 index 00000000000000..5d11923ab68307 --- /dev/null +++ b/src/plugins/visualizations/public/wizard/agg_based_selection/agg_based_selection.tsx @@ -0,0 +1,163 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { orderBy } from 'lodash'; +import React, { ChangeEvent } from 'react'; + +import { + EuiFieldSearch, + EuiFlexGrid, + EuiFlexItem, + EuiScreenReaderOnly, + EuiSpacer, + EuiIcon, + EuiCard, + EuiModalBody, + EuiModalHeader, + EuiModalHeaderTitle, +} from '@elastic/eui'; + +import { memoizeLast } from '../../legacy/memoize'; +import type { VisType, TypesStart } from '../../vis_types'; +import { VisGroups } from '../../vis_types'; +import { DialogNavigation } from '../dialog_navigation'; + +interface VisTypeListEntry { + type: VisType; + highlighted: boolean; +} + +interface AggBasedSelectionProps { + onVisTypeSelected: (visType: VisType) => void; + visTypesRegistry: TypesStart; + toggleGroups: (flag: boolean) => void; +} +interface AggBasedSelectionState { + query: string; +} + +class AggBasedSelection extends React.Component { + public state: AggBasedSelectionState = { + query: '', + }; + + private readonly getFilteredVisTypes = memoizeLast(this.filteredVisTypes); + + public render() { + const { query } = this.state; + const visTypes = this.getFilteredVisTypes(this.props.visTypesRegistry, query); + return ( + <> + + + + + + + this.props.toggleGroups(true)} /> + + + + + {query && ( + type.highlighted).length, + }} + /> + )} + + + + {visTypes.map(this.renderVisType)} + + + + ); + } + + private filteredVisTypes(visTypes: TypesStart, query: string): VisTypeListEntry[] { + const types = visTypes.getByGroup(VisGroups.AGGBASED).filter((type) => { + // Filter out hidden visualizations and visualizations that are only aggregations based + return !type.hidden; + }); + + let entries: VisTypeListEntry[]; + if (!query) { + entries = types.map((type) => ({ type, highlighted: false })); + } else { + const q = query.toLowerCase(); + entries = types.map((type) => { + const matchesQuery = + type.name.toLowerCase().includes(q) || + type.title.toLowerCase().includes(q) || + (typeof type.description === 'string' && type.description.toLowerCase().includes(q)); + return { type, highlighted: matchesQuery }; + }); + } + + return orderBy(entries, ['highlighted', 'type.title'], ['desc', 'asc']); + } + + private renderVisType = (visType: VisTypeListEntry) => { + const isDisabled = this.state.query !== '' && !visType.highlighted; + const onClick = () => this.props.onVisTypeSelected(visType.type); + + return ( + + {visType.type.title}} + onClick={onClick} + data-test-subj={`visType-${visType.type.name}`} + data-vis-stage={visType.type.stage} + aria-label={`visType-${visType.type.name}`} + description={visType.type.description || ''} + layout="horizontal" + isDisabled={isDisabled} + icon={} + /> + + ); + }; + + private onQueryChange = (ev: ChangeEvent) => { + this.setState({ + query: ev.target.value, + }); + }; +} + +export { AggBasedSelection }; diff --git a/src/plugins/visualizations/public/wizard/agg_based_selection/index.ts b/src/plugins/visualizations/public/wizard/agg_based_selection/index.ts new file mode 100644 index 00000000000000..c1dfab71cce499 --- /dev/null +++ b/src/plugins/visualizations/public/wizard/agg_based_selection/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { AggBasedSelection } from './agg_based_selection'; diff --git a/src/plugins/visualizations/public/wizard/_dialog.scss b/src/plugins/visualizations/public/wizard/dialog.scss similarity index 81% rename from src/plugins/visualizations/public/wizard/_dialog.scss rename to src/plugins/visualizations/public/wizard/dialog.scss index 793951f9dd1ca3..f0cc8381a67aab 100644 --- a/src/plugins/visualizations/public/wizard/_dialog.scss +++ b/src/plugins/visualizations/public/wizard/dialog.scss @@ -1,84 +1,57 @@ -.visNewVisDialog { - max-width: 100vw; - background-image: url(lightOrDarkTheme("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='313' height='461' viewBox='0 0 313 461'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath fill='%23F5F7FA' d='M294.009,184.137 C456.386,184.137 588.018,315.77 588.018,478.146 C588.018,640.523 456.386,772.156 294.009,772.156 C131.632,772.156 0,640.523 0,478.146 C0,315.77 131.632,184.137 294.009,184.137 Z M294.009,384.552 C242.318,384.552 200.415,426.456 200.415,478.146 C200.415,529.837 242.318,571.741 294.009,571.741 C345.7,571.741 387.604,529.837 387.604,478.146 C387.604,426.456 345.7,384.552 294.009,384.552 Z'/%3E%3Cpath fill='%23E6EBF2' d='M202.958,365.731 L202.958,380.991 L187.698,380.991 L187.698,365.731 L202.958,365.731 Z M202.958,327.073 L202.958,342.333 L187.698,342.333 L187.698,327.073 L202.958,327.073 Z M243.651,325.038 L243.651,340.298 L228.391,340.298 L228.391,325.038 L243.651,325.038 Z M243.651,286.379 L243.651,301.639 L228.391,301.639 L228.391,286.379 L243.651,286.379 Z M202.958,285.362 L202.958,300.622 L187.698,300.622 L187.698,285.362 L202.958,285.362 Z M284.345,284.345 L284.345,299.605 L269.085,299.605 L269.085,284.345 L284.345,284.345 Z M284.345,245.686 L284.345,260.946 L269.085,260.946 L269.085,245.686 L284.345,245.686 Z M243.651,244.669 L243.651,259.929 L228.391,259.929 L228.391,244.669 L243.651,244.669 Z M202.958,243.651 L202.958,258.911 L187.698,258.911 L187.698,243.651 L202.958,243.651 Z M284.345,203.975 L284.345,219.235 L269.085,219.235 L269.085,203.975 L284.345,203.975 Z M202.958,203.975 L202.958,219.235 L187.698,219.235 L187.698,203.975 L202.958,203.975 Z M243.651,202.958 L243.651,218.218 L228.391,218.218 L228.391,202.958 L243.651,202.958 Z M243.651,163.282 L243.651,178.542 L228.391,178.542 L228.391,163.282 L243.651,163.282 Z M202.958,163.282 L202.958,178.542 L187.698,178.542 L187.698,163.282 L202.958,163.282 Z M284.345,162.265 L284.345,177.525 L269.085,177.525 L269.085,162.265 L284.345,162.265 Z M284.345,122.589 L284.345,137.849 L269.085,137.849 L269.085,122.589 L284.345,122.589 Z M243.651,122.589 L243.651,137.849 L228.391,137.849 L228.391,122.589 L243.651,122.589 Z M202.958,122.589 L202.958,137.849 L187.698,137.849 L187.698,122.589 L202.958,122.589 Z M284.345,81.8954 L284.345,97.1554 L269.085,97.1554 L269.085,81.8954 L284.345,81.8954 Z M243.651,81.8954 L243.651,97.1554 L228.391,97.1554 L228.391,81.8954 L243.651,81.8954 Z M202.958,81.8954 L202.958,97.1554 L187.698,97.1554 L187.698,81.8954 L202.958,81.8954 Z M284.345,41.202 L284.345,56.462 L269.085,56.462 L269.085,41.202 L284.345,41.202 Z M243.651,41.202 L243.651,56.462 L228.391,56.462 L228.391,41.202 L243.651,41.202 Z M284.345,0.508789 L284.345,15.7688 L269.085,15.7688 L269.085,0.508789 L284.345,0.508789 Z'/%3E%3C/g%3E%3C/svg%3E","data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='313' height='461' viewBox='0 0 313 461'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath fill='%2318191E' d='M294.009,184.137 C456.386,184.137 588.018,315.77 588.018,478.146 C588.018,640.523 456.386,772.156 294.009,772.156 C131.632,772.156 0,640.523 0,478.146 C0,315.77 131.632,184.137 294.009,184.137 Z M294.009,384.552 C242.318,384.552 200.415,426.456 200.415,478.146 C200.415,529.837 242.318,571.741 294.009,571.741 C345.7,571.741 387.604,529.837 387.604,478.146 C387.604,426.456 345.7,384.552 294.009,384.552 Z'/%3E%3Cpath fill='%2315161B' d='M202.958,365.731 L202.958,380.991 L187.698,380.991 L187.698,365.731 L202.958,365.731 Z M202.958,327.073 L202.958,342.333 L187.698,342.333 L187.698,327.073 L202.958,327.073 Z M243.651,325.038 L243.651,340.298 L228.391,340.298 L228.391,325.038 L243.651,325.038 Z M243.651,286.379 L243.651,301.639 L228.391,301.639 L228.391,286.379 L243.651,286.379 Z M202.958,285.362 L202.958,300.622 L187.698,300.622 L187.698,285.362 L202.958,285.362 Z M284.345,284.345 L284.345,299.605 L269.085,299.605 L269.085,284.345 L284.345,284.345 Z M284.345,245.686 L284.345,260.946 L269.085,260.946 L269.085,245.686 L284.345,245.686 Z M243.651,244.669 L243.651,259.929 L228.391,259.929 L228.391,244.669 L243.651,244.669 Z M202.958,243.651 L202.958,258.911 L187.698,258.911 L187.698,243.651 L202.958,243.651 Z M284.345,203.975 L284.345,219.235 L269.085,219.235 L269.085,203.975 L284.345,203.975 Z M202.958,203.975 L202.958,219.235 L187.698,219.235 L187.698,203.975 L202.958,203.975 Z M243.651,202.958 L243.651,218.218 L228.391,218.218 L228.391,202.958 L243.651,202.958 Z M243.651,163.282 L243.651,178.542 L228.391,178.542 L228.391,163.282 L243.651,163.282 Z M202.958,163.282 L202.958,178.542 L187.698,178.542 L187.698,163.282 L202.958,163.282 Z M284.345,162.265 L284.345,177.525 L269.085,177.525 L269.085,162.265 L284.345,162.265 Z M284.345,122.589 L284.345,137.849 L269.085,137.849 L269.085,122.589 L284.345,122.589 Z M243.651,122.589 L243.651,137.849 L228.391,137.849 L228.391,122.589 L243.651,122.589 Z M202.958,122.589 L202.958,137.849 L187.698,137.849 L187.698,122.589 L202.958,122.589 Z M284.345,81.8954 L284.345,97.1554 L269.085,97.1554 L269.085,81.8954 L284.345,81.8954 Z M243.651,81.8954 L243.651,97.1554 L228.391,97.1554 L228.391,81.8954 L243.651,81.8954 Z M202.958,81.8954 L202.958,97.1554 L187.698,97.1554 L187.698,81.8954 L202.958,81.8954 Z M284.345,41.202 L284.345,56.462 L269.085,56.462 L269.085,41.202 L284.345,41.202 Z M243.651,41.202 L243.651,56.462 L228.391,56.462 L228.391,41.202 L243.651,41.202 Z M284.345,0.508789 L284.345,15.7688 L269.085,15.7688 L269.085,0.508789 L284.345,0.508789 Z'/%3E%3C/g%3E%3C/svg%3E")); - background-repeat: no-repeat; - background-position: calc(100% + 1px) calc(100% + 1px); - background-size: 30%; -} +$modalWidth: $euiSizeL * 34; +$modalHeight: $euiSizeL * 30; -.visNewVisSearchDialog { - width: $euiSizeL * 30; - min-height: $euiSizeL * 25; -} - -.visNewVisDialog__body { - display: flex; - padding: $euiSizeM $euiSizeL 0; - min-height: 0; -} -.visNewVisDialog__list { - min-height: 0; -} +.visNewVisDialog { + @include euiBreakpoint('xs', 's') { + max-height: 100%; + } -.visNewVisDialog__searchWrapper { - flex-shrink: 0; + max-width: $modalWidth; + max-height: $modalHeight; + background: $euiColorEmptyShade; } -.visNewVisDialog__typesWrapper { - @include euiOverflowShadow; - max-width: $euiSizeXXL * 10; - min-height: 0; - margin-top: 2px; // Account for search field dropshadow - overflow: hidden; -} +.visNewVisDialog--aggbased { + @include euiBreakpoint('xs', 's') { + max-height: 100%; + } -.visNewVisDialog__types { - @include euiScrollBar; - // EUITODO: allow for more (calculated) widths of `EuiKeyPadMenu` - width: auto; - overflow-y: auto; - padding-top: $euiSize; - justify-content: center; - padding-bottom: $euiSize; + max-width: $modalWidth; + max-height: $modalHeight; + background-repeat: no-repeat; + background-position: calc(100% + 1px) calc(100% + 1px); + background-size: 30%; + // sass-lint:disable-block quotes space-after-comma + background-image: url(lightOrDarkTheme("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='313' height='461' viewBox='0 0 313 461'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath fill='%23F5F7FA' d='M294.009,184.137 C456.386,184.137 588.018,315.77 588.018,478.146 C588.018,640.523 456.386,772.156 294.009,772.156 C131.632,772.156 0,640.523 0,478.146 C0,315.77 131.632,184.137 294.009,184.137 Z M294.009,384.552 C242.318,384.552 200.415,426.456 200.415,478.146 C200.415,529.837 242.318,571.741 294.009,571.741 C345.7,571.741 387.604,529.837 387.604,478.146 C387.604,426.456 345.7,384.552 294.009,384.552 Z'/%3E%3Cpath fill='%23E6EBF2' d='M202.958,365.731 L202.958,380.991 L187.698,380.991 L187.698,365.731 L202.958,365.731 Z M202.958,327.073 L202.958,342.333 L187.698,342.333 L187.698,327.073 L202.958,327.073 Z M243.651,325.038 L243.651,340.298 L228.391,340.298 L228.391,325.038 L243.651,325.038 Z M243.651,286.379 L243.651,301.639 L228.391,301.639 L228.391,286.379 L243.651,286.379 Z M202.958,285.362 L202.958,300.622 L187.698,300.622 L187.698,285.362 L202.958,285.362 Z M284.345,284.345 L284.345,299.605 L269.085,299.605 L269.085,284.345 L284.345,284.345 Z M284.345,245.686 L284.345,260.946 L269.085,260.946 L269.085,245.686 L284.345,245.686 Z M243.651,244.669 L243.651,259.929 L228.391,259.929 L228.391,244.669 L243.651,244.669 Z M202.958,243.651 L202.958,258.911 L187.698,258.911 L187.698,243.651 L202.958,243.651 Z M284.345,203.975 L284.345,219.235 L269.085,219.235 L269.085,203.975 L284.345,203.975 Z M202.958,203.975 L202.958,219.235 L187.698,219.235 L187.698,203.975 L202.958,203.975 Z M243.651,202.958 L243.651,218.218 L228.391,218.218 L228.391,202.958 L243.651,202.958 Z M243.651,163.282 L243.651,178.542 L228.391,178.542 L228.391,163.282 L243.651,163.282 Z M202.958,163.282 L202.958,178.542 L187.698,178.542 L187.698,163.282 L202.958,163.282 Z M284.345,162.265 L284.345,177.525 L269.085,177.525 L269.085,162.265 L284.345,162.265 Z M284.345,122.589 L284.345,137.849 L269.085,137.849 L269.085,122.589 L284.345,122.589 Z M243.651,122.589 L243.651,137.849 L228.391,137.849 L228.391,122.589 L243.651,122.589 Z M202.958,122.589 L202.958,137.849 L187.698,137.849 L187.698,122.589 L202.958,122.589 Z M284.345,81.8954 L284.345,97.1554 L269.085,97.1554 L269.085,81.8954 L284.345,81.8954 Z M243.651,81.8954 L243.651,97.1554 L228.391,97.1554 L228.391,81.8954 L243.651,81.8954 Z M202.958,81.8954 L202.958,97.1554 L187.698,97.1554 L187.698,81.8954 L202.958,81.8954 Z M284.345,41.202 L284.345,56.462 L269.085,56.462 L269.085,41.202 L284.345,41.202 Z M243.651,41.202 L243.651,56.462 L228.391,56.462 L228.391,41.202 L243.651,41.202 Z M284.345,0.508789 L284.345,15.7688 L269.085,15.7688 L269.085,0.508789 L284.345,0.508789 Z'/%3E%3C/g%3E%3C/svg%3E","data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='313' height='461' viewBox='0 0 313 461'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath fill='%2318191E' d='M294.009,184.137 C456.386,184.137 588.018,315.77 588.018,478.146 C588.018,640.523 456.386,772.156 294.009,772.156 C131.632,772.156 0,640.523 0,478.146 C0,315.77 131.632,184.137 294.009,184.137 Z M294.009,384.552 C242.318,384.552 200.415,426.456 200.415,478.146 C200.415,529.837 242.318,571.741 294.009,571.741 C345.7,571.741 387.604,529.837 387.604,478.146 C387.604,426.456 345.7,384.552 294.009,384.552 Z'/%3E%3Cpath fill='%2315161B' d='M202.958,365.731 L202.958,380.991 L187.698,380.991 L187.698,365.731 L202.958,365.731 Z M202.958,327.073 L202.958,342.333 L187.698,342.333 L187.698,327.073 L202.958,327.073 Z M243.651,325.038 L243.651,340.298 L228.391,340.298 L228.391,325.038 L243.651,325.038 Z M243.651,286.379 L243.651,301.639 L228.391,301.639 L228.391,286.379 L243.651,286.379 Z M202.958,285.362 L202.958,300.622 L187.698,300.622 L187.698,285.362 L202.958,285.362 Z M284.345,284.345 L284.345,299.605 L269.085,299.605 L269.085,284.345 L284.345,284.345 Z M284.345,245.686 L284.345,260.946 L269.085,260.946 L269.085,245.686 L284.345,245.686 Z M243.651,244.669 L243.651,259.929 L228.391,259.929 L228.391,244.669 L243.651,244.669 Z M202.958,243.651 L202.958,258.911 L187.698,258.911 L187.698,243.651 L202.958,243.651 Z M284.345,203.975 L284.345,219.235 L269.085,219.235 L269.085,203.975 L284.345,203.975 Z M202.958,203.975 L202.958,219.235 L187.698,219.235 L187.698,203.975 L202.958,203.975 Z M243.651,202.958 L243.651,218.218 L228.391,218.218 L228.391,202.958 L243.651,202.958 Z M243.651,163.282 L243.651,178.542 L228.391,178.542 L228.391,163.282 L243.651,163.282 Z M202.958,163.282 L202.958,178.542 L187.698,178.542 L187.698,163.282 L202.958,163.282 Z M284.345,162.265 L284.345,177.525 L269.085,177.525 L269.085,162.265 L284.345,162.265 Z M284.345,122.589 L284.345,137.849 L269.085,137.849 L269.085,122.589 L284.345,122.589 Z M243.651,122.589 L243.651,137.849 L228.391,137.849 L228.391,122.589 L243.651,122.589 Z M202.958,122.589 L202.958,137.849 L187.698,137.849 L187.698,122.589 L202.958,122.589 Z M284.345,81.8954 L284.345,97.1554 L269.085,97.1554 L269.085,81.8954 L284.345,81.8954 Z M243.651,81.8954 L243.651,97.1554 L228.391,97.1554 L228.391,81.8954 L243.651,81.8954 Z M202.958,81.8954 L202.958,97.1554 L187.698,97.1554 L187.698,81.8954 L202.958,81.8954 Z M284.345,41.202 L284.345,56.462 L269.085,56.462 L269.085,41.202 L284.345,41.202 Z M243.651,41.202 L243.651,56.462 L228.391,56.462 L228.391,41.202 L243.651,41.202 Z M284.345,0.508789 L284.345,15.7688 L269.085,15.7688 L269.085,0.508789 L284.345,0.508789 Z'/%3E%3C/g%3E%3C/svg%3E")); } -.visNewVisDialog__description { - width: $euiSizeXL * 10; +.visNewVisSearchDialog { + min-width: $modalWidth; + min-height: $modalHeight; } -.visNewVisDialog__type:disabled { - opacity: 0.2; - pointer-events: none; +.visNewVisDialog__toolsCard { + background-color: transparent; } -.visNewVisDialog__typeImage { - @include size($euiSizeL); +.visNewVisDialog__groupsCard { + background-color: transparent; + box-shadow: none; } -@include euiBreakpoint('xs', 's') { - .visNewVisDialog { - background-image: none; - } - - .visNewVisDialog__typesWrapper { - max-width: none; - } - - .visNewVisDialog__types { - justify-content: flex-start; - } +.visNewVisDialog__groupsCardWrapper { + position: relative; - .visNewVisDialog__description { - display: none; + .visNewVisDialog__groupsCardLink { + position: absolute; + left: 50%; + transform: translateX(-50%); + margin-top: - $euiSizeM; } -} -@include internetExplorerOnly { - .visNewVisDialog { - width: 820px; + // overrides EuiBetaBadge specificity + .visNewVisDialog__groupsCardBetaBadge { + background: $euiColorEmptyShade; + cursor: pointer; } - - .visNewVisDialog__body { - flex-basis: 800px; - } -} +} \ No newline at end of file diff --git a/src/plugins/visualizations/public/wizard/dialog_navigation.tsx b/src/plugins/visualizations/public/wizard/dialog_navigation.tsx new file mode 100644 index 00000000000000..aa8e4c5580f523 --- /dev/null +++ b/src/plugins/visualizations/public/wizard/dialog_navigation.tsx @@ -0,0 +1,48 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { EuiLink, EuiIcon, EuiSpacer, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; + +interface DialogNavigationProps { + goBack: () => void; +} + +function DialogNavigation(props: DialogNavigationProps) { + return ( + <> + + + + + + + {i18n.translate('visualizations.newVisWizard.goBackLink', { + defaultMessage: 'Go back', + })} + + + + + + ); +} + +export { DialogNavigation }; diff --git a/src/plugins/visualizations/public/wizard/group_selection/group_selection.scss b/src/plugins/visualizations/public/wizard/group_selection/group_selection.scss new file mode 100644 index 00000000000000..ce46b872a97ee5 --- /dev/null +++ b/src/plugins/visualizations/public/wizard/group_selection/group_selection.scss @@ -0,0 +1,30 @@ +.visNewVisDialogGroupSelection__body { + // override EUI specificity + .euiModalBody__overflow { + padding: 0 !important; // sass-lint:disable-line no-important + } +} + +.visNewVisDialogGroupSelection__visGroups { + padding: $euiSizeS $euiSizeXL 0; +} + +.visNewVisDialogGroupSelection__footer { + @include euiBreakpoint('xs', 's') { + background: $euiColorEmptyShade; + } + + padding: 0 $euiSizeXL $euiSizeL; + background: $euiColorLightestShade; +} + +.visNewVisDialogGroupSelection__footerDescriptionList { + @include euiBreakpoint('xs', 's') { + padding-top: $euiSizeL; + } +} + +.visNewVisDialogGroupSelection__footerDescriptionListTitle { + // override EUI specificity + width: auto !important; // sass-lint:disable-line no-important +} diff --git a/src/plugins/visualizations/public/wizard/group_selection/group_selection.test.tsx b/src/plugins/visualizations/public/wizard/group_selection/group_selection.test.tsx new file mode 100644 index 00000000000000..b357f42bbae8bc --- /dev/null +++ b/src/plugins/visualizations/public/wizard/group_selection/group_selection.test.tsx @@ -0,0 +1,321 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { mountWithIntl } from 'test_utils/enzyme_helpers'; +import { TypesStart, VisType, VisGroups } from '../../vis_types'; +import { GroupSelection } from './group_selection'; +import { DocLinksStart } from '../../../../../core/public'; + +describe('GroupSelection', () => { + const defaultVisTypeParams = { + hidden: false, + visualization: class Controller { + public render = jest.fn(); + public destroy = jest.fn(); + }, + requiresSearch: false, + requestHandler: 'none', + responseHandler: 'none', + }; + const _visTypes = [ + { + name: 'vis1', + title: 'Vis Type 1', + description: 'Vis Type 1', + stage: 'production', + group: VisGroups.PROMOTED, + ...defaultVisTypeParams, + }, + { + name: 'vis2', + title: 'Vis Type 2', + description: 'Vis Type 2', + group: VisGroups.PROMOTED, + stage: 'production', + ...defaultVisTypeParams, + }, + { + name: 'visWithAliasUrl', + title: 'Vis with alias Url', + aliasApp: 'aliasApp', + aliasPath: '#/aliasApp', + disabled: true, + promoTooltip: { + description: 'Learn More', + link: '#/anotherUrl', + }, + description: 'Vis with alias Url', + stage: 'production', + group: VisGroups.PROMOTED, + }, + { + name: 'visAliasWithPromotion', + title: 'Vis alias with promotion', + description: 'Vis alias with promotion', + stage: 'production', + group: VisGroups.PROMOTED, + aliasApp: 'anotherApp', + aliasPath: '#/anotherUrl', + promotion: true, + } as unknown, + ] as VisType[]; + + const visTypesRegistry = (visTypes: VisType[]): TypesStart => { + return { + get(id: string): VisType { + return (visTypes.find((vis) => vis.name === id) as unknown) as VisType; + }, + all: () => { + return (visTypes as unknown) as VisType[]; + }, + getAliases: () => [], + unRegisterAlias: () => [], + getByGroup: (group: VisGroups) => { + return (visTypes.filter((type) => { + return type.group === group; + }) as unknown) as VisType[]; + }, + }; + }; + + const docLinks = { + links: { + dashboard: { + guide: 'test', + }, + }, + }; + + beforeAll(() => { + Object.defineProperty(window, 'location', { + value: { + assign: jest.fn(), + }, + }); + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should render the header title', () => { + const wrapper = mountWithIntl( + + ); + expect(wrapper.find('[data-test-subj="groupModalHeader"]').at(0).text()).toBe( + 'New visualization' + ); + }); + + it('should not render the aggBased group card if no aggBased visualization is registered', () => { + const wrapper = mountWithIntl( + + ); + expect(wrapper.find('[data-test-subj="visGroup-aggbased"]').exists()).toBe(false); + }); + + it('should render the aggBased group card if an aggBased group vis is registered', () => { + const aggBasedVisType = { + name: 'visWithSearch', + title: 'Vis with search', + group: VisGroups.AGGBASED, + stage: 'production', + ...defaultVisTypeParams, + }; + const wrapper = mountWithIntl( + + ); + expect(wrapper.find('[data-test-subj="visGroup-aggbased"]').exists()).toBe(true); + }); + + it('should not render the tools group card if no tools visualization is registered', () => { + const wrapper = mountWithIntl( + + ); + expect(wrapper.find('[data-test-subj="visGroup-tools"]').exists()).toBe(false); + }); + + it('should render the tools group card if a tools group vis is registered', () => { + const toolsVisType = { + name: 'vis3', + title: 'Vis3', + stage: 'production', + group: VisGroups.TOOLS, + ...defaultVisTypeParams, + }; + const wrapper = mountWithIntl( + + ); + expect(wrapper.find('[data-test-subj="visGroup-tools"]').exists()).toBe(true); + }); + + it('should call the toggleGroups if the aggBased group card is clicked', () => { + const toggleGroups = jest.fn(); + const aggBasedVisType = { + name: 'visWithSearch', + title: 'Vis with search', + group: VisGroups.AGGBASED, + stage: 'production', + ...defaultVisTypeParams, + }; + const wrapper = mountWithIntl( + + ); + const aggBasedGroupCard = wrapper.find('[data-test-subj="visGroupAggBasedExploreLink"]').at(0); + aggBasedGroupCard.simulate('click'); + expect(toggleGroups).toHaveBeenCalled(); + }); + + it('should sort promoted visualizations first', () => { + const wrapper = mountWithIntl( + + ); + + const cards = [ + ...new Set( + wrapper.find('[data-test-subj^="visType-"]').map((card) => card.prop('data-test-subj')) + ), + ]; + + expect(cards).toEqual([ + 'visType-visAliasWithPromotion', + 'visType-vis1', + 'visType-vis2', + 'visType-visWithAliasUrl', + ]); + }); + + it('should render disabled aliases with a disabled class', () => { + const wrapper = mountWithIntl( + + ); + expect(wrapper.find('[data-test-subj="visType-visWithAliasUrl"]').exists()).toBe(true); + expect( + wrapper + .find('[data-test-subj="visType-visWithAliasUrl"]') + .at(1) + .hasClass('euiCard-isDisabled') + ).toBe(true); + }); + + it('should render a basic badge with link for disabled aliases with promoTooltip', () => { + const wrapper = mountWithIntl( + + ); + expect(wrapper.find('[data-test-subj="visTypeBadge"]').exists()).toBe(true); + expect(wrapper.find('[data-test-subj="visTypeBadge"]').at(0).prop('tooltipContent')).toBe( + 'Learn More' + ); + }); + + it('should not show tools experimental visualizations if showExperimentalis false', () => { + const expVis = { + name: 'visExp', + title: 'Experimental Vis', + group: VisGroups.TOOLS, + stage: 'experimental', + ...defaultVisTypeParams, + }; + const wrapper = mountWithIntl( + + ); + expect(wrapper.find('[data-test-subj="visType-visExp"]').exists()).toBe(false); + }); + + it('should show tools experimental visualizations if showExperimental is true', () => { + const expVis = { + name: 'visExp', + title: 'Experimental Vis', + group: VisGroups.TOOLS, + stage: 'experimental', + ...defaultVisTypeParams, + }; + const wrapper = mountWithIntl( + + ); + expect(wrapper.find('[data-test-subj="visType-visExp"]').exists()).toBe(true); + }); +}); diff --git a/src/plugins/visualizations/public/wizard/group_selection/group_selection.tsx b/src/plugins/visualizations/public/wizard/group_selection/group_selection.tsx new file mode 100644 index 00000000000000..8520b84cc42adb --- /dev/null +++ b/src/plugins/visualizations/public/wizard/group_selection/group_selection.tsx @@ -0,0 +1,294 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { FormattedMessage } from '@kbn/i18n/react'; +import React, { useCallback, useMemo } from 'react'; +import { orderBy } from 'lodash'; +import { + EuiFlexGroup, + EuiFlexGrid, + EuiFlexItem, + EuiCard, + EuiIcon, + EuiModalHeader, + EuiModalBody, + EuiModalHeaderTitle, + EuiLink, + EuiText, + EuiSpacer, + EuiBetaBadge, + EuiTitle, + EuiDescriptionListTitle, + EuiDescriptionListDescription, + EuiDescriptionList, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { DocLinksStart } from '../../../../../core/public'; +import { VisTypeAlias } from '../../vis_types/vis_type_alias_registry'; +import type { VisType, TypesStart } from '../../vis_types'; +import { VisGroups } from '../../vis_types'; +import './group_selection.scss'; + +interface GroupSelectionProps { + onVisTypeSelected: (visType: VisType | VisTypeAlias) => void; + visTypesRegistry: TypesStart; + docLinks: DocLinksStart; + toggleGroups: (flag: boolean) => void; + showExperimental: boolean; +} + +interface VisCardProps { + onVisTypeSelected: (visType: VisType | VisTypeAlias) => void; + visType: VisType | VisTypeAlias; + showExperimental?: boolean | undefined; +} + +function isVisTypeAlias(type: VisType | VisTypeAlias): type is VisTypeAlias { + return 'aliasPath' in type; +} + +function GroupSelection(props: GroupSelectionProps) { + const visualizeGuideLink = props.docLinks.links.dashboard.guide; + const promotedVisGroups = useMemo( + () => + orderBy( + [ + ...props.visTypesRegistry.getAliases(), + ...props.visTypesRegistry.getByGroup(VisGroups.PROMOTED), + ], + ['promotion', 'title'], + ['asc', 'asc'] + ), + [props.visTypesRegistry] + ); + return ( + <> + + + + + + +
+ + + {promotedVisGroups.map((visType) => ( + + ))} + + +
+
+ + + {props.visTypesRegistry.getByGroup(VisGroups.AGGBASED).length > 0 && ( + + props.toggleGroups(false)} + title={ + + {i18n.translate('visualizations.newVisWizard.aggBasedGroupTitle', { + defaultMessage: 'Aggregation based', + })} + + } + data-test-subj="visGroup-aggbased" + description={i18n.translate( + 'visualizations.newVisWizard.aggBasedGroupDescription', + { + defaultMessage: + 'Use our classic visualize library to create charts based on aggregations.', + } + )} + icon={} + className="visNewVisDialog__groupsCard" + > + props.toggleGroups(false)} + > + + {i18n.translate('visualizations.newVisWizard.exploreOptionLinkText', { + defaultMessage: 'Explore options', + })}{' '} + + + + + + )} + {props.visTypesRegistry.getByGroup(VisGroups.TOOLS).length > 0 && ( + + + + + {i18n.translate('visualizations.newVisWizard.toolsGroupTitle', { + defaultMessage: 'Tools', + })} + + + +
+ {props.visTypesRegistry.getByGroup(VisGroups.TOOLS).map((visType) => ( + + ))} +
+
+ )} +
+ + + + + + + + + + + +
+
+ + ); +} + +const VisGroup = ({ visType, onVisTypeSelected }: VisCardProps) => { + const onClick = useCallback(() => { + onVisTypeSelected(visType); + }, [onVisTypeSelected, visType]); + const shouldDisableCard = isVisTypeAlias(visType) && visType.disabled; + const betaBadgeContent = + shouldDisableCard && 'promoTooltip' in visType ? ( + + + + ) : undefined; + return ( + + {betaBadgeContent} + + {'titleInWizard' in visType && visType.titleInWizard + ? visType.titleInWizard + : visType.title} + + } + onClick={onClick} + isDisabled={shouldDisableCard} + data-test-subj={`visType-${visType.name}`} + data-vis-stage={!('aliasPath' in visType) ? visType.stage : 'alias'} + aria-label={`visType-${visType.name}`} + description={ + <> + {visType.description || ''} + {visType.note || ''} + + } + layout="horizontal" + icon={} + className="visNewVisDialog__groupsCard" + /> + + ); +}; + +const ToolsGroup = ({ visType, onVisTypeSelected, showExperimental }: VisCardProps) => { + const onClick = useCallback(() => { + onVisTypeSelected(visType); + }, [onVisTypeSelected, visType]); + // hide the experimental visualization if lab mode is not enabled + if (!showExperimental && visType.stage === 'experimental') { + return null; + } + return ( + + + + + + + + + {'titleInWizard' in visType && visType.titleInWizard + ? visType.titleInWizard + : visType.title} + + + {visType.stage === 'experimental' && ( + + + + )} + + + {visType.description} + + + + ); +}; + +export { GroupSelection }; diff --git a/src/plugins/visualizations/public/wizard/group_selection/index.ts b/src/plugins/visualizations/public/wizard/group_selection/index.ts new file mode 100644 index 00000000000000..80bd3dda7ac40f --- /dev/null +++ b/src/plugins/visualizations/public/wizard/group_selection/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { GroupSelection } from './group_selection'; diff --git a/src/plugins/visualizations/public/wizard/new_vis_modal.test.tsx b/src/plugins/visualizations/public/wizard/new_vis_modal.test.tsx index 51bcfed2016874..eea364b754e31e 100644 --- a/src/plugins/visualizations/public/wizard/new_vis_modal.test.tsx +++ b/src/plugins/visualizations/public/wizard/new_vis_modal.test.tsx @@ -19,9 +19,9 @@ import React from 'react'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; -import { TypesStart, VisType } from '../vis_types'; -import { NewVisModal } from './new_vis_modal'; -import { ApplicationStart, SavedObjectsStart } from '../../../../core/public'; +import { TypesStart, VisType, VisGroups } from '../vis_types'; +import NewVisModal from './new_vis_modal'; +import { ApplicationStart, SavedObjectsStart, DocLinksStart } from '../../../../core/public'; import { embeddablePluginMock } from '../../../embeddable/public/mocks'; describe('NewVisModal', () => { @@ -36,31 +36,41 @@ describe('NewVisModal', () => { responseHandler: 'none', }; const _visTypes = [ - { name: 'vis', title: 'Vis Type 1', stage: 'production', ...defaultVisTypeParams }, - { name: 'visExp', title: 'Experimental Vis', stage: 'experimental', ...defaultVisTypeParams }, { - name: 'visWithSearch', - title: 'Vis with search', + name: 'vis', + title: 'Vis Type 1', + stage: 'production', + group: VisGroups.PROMOTED, + ...defaultVisTypeParams, + }, + { + name: 'vis2', + title: 'Vis Type 2', + group: VisGroups.PROMOTED, stage: 'production', ...defaultVisTypeParams, }, + { + name: 'vis3', + title: 'Vis3', + stage: 'production', + group: VisGroups.TOOLS, + ...defaultVisTypeParams, + }, { name: 'visWithAliasUrl', title: 'Vis with alias Url', stage: 'production', + group: VisGroups.PROMOTED, aliasApp: 'otherApp', aliasPath: '#/aliasUrl', }, { - name: 'visAliasWithPromotion', - title: 'Vis alias with promotion', + name: 'visWithSearch', + title: 'Vis with search', + group: VisGroups.AGGBASED, stage: 'production', - aliasApp: 'anotherApp', - aliasPath: '#/anotherUrl', - promotion: { - description: 'promotion description', - buttonText: 'another app', - }, + ...defaultVisTypeParams, }, ]; const visTypes: TypesStart = { @@ -71,10 +81,23 @@ describe('NewVisModal', () => { return (_visTypes as unknown) as VisType[]; }, getAliases: () => [], + unRegisterAlias: () => [], + getByGroup: (group: VisGroups) => { + return (_visTypes.filter((type) => { + return type.group === group; + }) as unknown) as VisType[]; + }, }; const addBasePath = (url: string) => `testbasepath${url}`; const settingsGet = jest.fn(); const uiSettings: any = { get: settingsGet }; + const docLinks = { + links: { + dashboard: { + guide: 'test', + }, + }, + }; beforeAll(() => { Object.defineProperty(window, 'location', { @@ -88,7 +111,7 @@ describe('NewVisModal', () => { jest.clearAllMocks(); }); - it('should render as expected', () => { + it('should show the aggbased group but not the visualization assigned to this group', () => { const wrapper = mountWithIntl( { addBasePath={addBasePath} uiSettings={uiSettings} application={{} as ApplicationStart} + docLinks={docLinks as DocLinksStart} savedObjects={{} as SavedObjectsStart} /> ); - expect(wrapper).toMatchSnapshot(); + expect(wrapper.find('[data-test-subj="visGroup-aggbased"]').exists()).toBe(true); + expect(wrapper.find('[data-test-subj="visType-visWithSearch"]').exists()).toBe(false); }); - it('should show a button for regular visualizations', () => { + it('should show the tools group', () => { const wrapper = mountWithIntl( { addBasePath={addBasePath} uiSettings={uiSettings} application={{} as ApplicationStart} + docLinks={docLinks as DocLinksStart} savedObjects={{} as SavedObjectsStart} /> ); - expect(wrapper.find('[data-test-subj="visType-vis"]').exists()).toBe(true); + expect(wrapper.find('[data-test-subj="visGroup-tools"]').exists()).toBe(true); }); - it('should sort promoted visualizations first', () => { + it('should display the visualizations of the other group', () => { const wrapper = mountWithIntl( { addBasePath={addBasePath} uiSettings={uiSettings} application={{} as ApplicationStart} + docLinks={docLinks as DocLinksStart} savedObjects={{} as SavedObjectsStart} /> ); - expect( - wrapper - .find('button[data-test-subj^="visType-"]') - .map((button) => button.prop('data-test-subj')) - ).toEqual([ - 'visType-visAliasWithPromotion', - 'visType-vis', - 'visType-visWithAliasUrl', - 'visType-visWithSearch', - ]); + expect(wrapper.find('[data-test-subj="visType-vis2"]').exists()).toBe(true); }); describe('open editor', () => { @@ -152,11 +170,12 @@ describe('NewVisModal', () => { addBasePath={addBasePath} uiSettings={uiSettings} application={{} as ApplicationStart} + docLinks={docLinks as DocLinksStart} savedObjects={{} as SavedObjectsStart} /> ); - const visButton = wrapper.find('button[data-test-subj="visType-vis"]'); - visButton.simulate('click'); + const visCard = wrapper.find('[data-test-subj="visType-vis"]').at(0); + visCard.simulate('click'); expect(window.location.assign).toBeCalledWith('testbasepath/app/visualize#/create?type=vis'); }); @@ -170,11 +189,12 @@ describe('NewVisModal', () => { addBasePath={addBasePath} uiSettings={uiSettings} application={{} as ApplicationStart} + docLinks={docLinks as DocLinksStart} savedObjects={{} as SavedObjectsStart} /> ); - const visButton = wrapper.find('button[data-test-subj="visType-vis"]'); - visButton.simulate('click'); + const visCard = wrapper.find('[data-test-subj="visType-vis"]').at(0); + visCard.simulate('click'); expect(window.location.assign).toBeCalledWith( 'testbasepath/app/visualize#/create?type=vis&foo=true&bar=42' ); @@ -194,12 +214,13 @@ describe('NewVisModal', () => { addBasePath={addBasePath} uiSettings={uiSettings} application={({ navigateToApp } as unknown) as ApplicationStart} + docLinks={docLinks as DocLinksStart} stateTransfer={stateTransfer} savedObjects={{} as SavedObjectsStart} /> ); - const visButton = wrapper.find('button[data-test-subj="visType-visWithAliasUrl"]'); - visButton.simulate('click'); + const visCard = wrapper.find('[data-test-subj="visType-visWithAliasUrl"]').at(0); + visCard.simulate('click'); expect(stateTransfer.navigateToEditor).toBeCalledWith('otherApp', { path: '#/aliasUrl', state: { originatingApp: 'coolJestTestApp' }, @@ -219,17 +240,18 @@ describe('NewVisModal', () => { addBasePath={addBasePath} uiSettings={uiSettings} application={({ navigateToApp } as unknown) as ApplicationStart} + docLinks={docLinks as DocLinksStart} savedObjects={{} as SavedObjectsStart} /> ); - const visButton = wrapper.find('button[data-test-subj="visType-visWithAliasUrl"]'); - visButton.simulate('click'); + const visCard = wrapper.find('[data-test-subj="visType-visWithAliasUrl"]').at(0); + visCard.simulate('click'); expect(navigateToApp).toBeCalledWith('otherApp', { path: '#/aliasUrl' }); expect(onClose).toHaveBeenCalled(); }); }); - describe('filter for visualization types', () => { + describe('aggBased visualizations', () => { it('should render as expected', () => { const wrapper = mountWithIntl( { addBasePath={addBasePath} uiSettings={uiSettings} application={{} as ApplicationStart} + docLinks={docLinks as DocLinksStart} savedObjects={{} as SavedObjectsStart} /> ); - const searchBox = wrapper.find('input[data-test-subj="filterVisType"]'); - searchBox.simulate('change', { target: { value: 'with' } }); - expect(wrapper).toMatchSnapshot(); - }); - }); - - describe('experimental visualizations', () => { - it('should not show experimental visualizations if visualize:enableLabs is false', () => { - settingsGet.mockReturnValue(false); - const wrapper = mountWithIntl( - null} - visTypesRegistry={visTypes} - addBasePath={addBasePath} - uiSettings={uiSettings} - application={{} as ApplicationStart} - savedObjects={{} as SavedObjectsStart} - /> - ); - expect(wrapper.find('[data-test-subj="visType-visExp"]').exists()).toBe(false); - }); - - it('should show experimental visualizations if visualize:enableLabs is true', () => { - settingsGet.mockReturnValue(true); - const wrapper = mountWithIntl( - null} - visTypesRegistry={visTypes} - addBasePath={addBasePath} - uiSettings={uiSettings} - application={{} as ApplicationStart} - savedObjects={{} as SavedObjectsStart} - /> - ); - expect(wrapper.find('[data-test-subj="visType-visExp"]').exists()).toBe(true); + const aggBasedGroupCard = wrapper + .find('[data-test-subj="visGroupAggBasedExploreLink"]') + .at(0); + aggBasedGroupCard.simulate('click'); + expect(wrapper.find('[data-test-subj="visType-visWithSearch"]').exists()).toBe(true); }); }); }); diff --git a/src/plugins/visualizations/public/wizard/new_vis_modal.tsx b/src/plugins/visualizations/public/wizard/new_vis_modal.tsx index 4bedd3eb1c22ae..fbd4e6ef80d5a2 100644 --- a/src/plugins/visualizations/public/wizard/new_vis_modal.tsx +++ b/src/plugins/visualizations/public/wizard/new_vis_modal.tsx @@ -23,13 +23,20 @@ import { EuiModal, EuiOverlayMask } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { METRIC_TYPE, UiStatsMetricType } from '@kbn/analytics'; -import { ApplicationStart, IUiSettingsClient, SavedObjectsStart } from '../../../../core/public'; +import { + ApplicationStart, + IUiSettingsClient, + SavedObjectsStart, + DocLinksStart, +} from '../../../../core/public'; import { SearchSelection } from './search_selection'; -import { TypeSelection } from './type_selection'; -import { TypesStart, VisType, VisTypeAlias } from '../vis_types'; +import { GroupSelection } from './group_selection'; +import { AggBasedSelection } from './agg_based_selection'; +import type { TypesStart, VisType, VisTypeAlias } from '../vis_types'; import { UsageCollectionSetup } from '../../../../plugins/usage_collection/public'; import { EmbeddableStateTransfer } from '../../../embeddable/public'; import { VISUALIZE_ENABLE_LABS_SETTING } from '../../common/constants'; +import './dialog.scss'; interface TypeSelectionProps { isOpen: boolean; @@ -38,6 +45,7 @@ interface TypeSelectionProps { editorParams?: string[]; addBasePath: (path: string) => string; uiSettings: IUiSettingsClient; + docLinks: DocLinksStart; savedObjects: SavedObjectsStart; usageCollection?: UsageCollectionSetup; application: ApplicationStart; @@ -48,6 +56,7 @@ interface TypeSelectionProps { interface TypeSelectionState { showSearchVisModal: boolean; + showGroups: boolean; visType?: VisType; } @@ -72,6 +81,7 @@ class NewVisModal extends React.Component @@ -101,19 +113,21 @@ class NewVisModal extends React.Component this.setState({ showSearchVisModal: false })} /> ) : ( - this.setState({ showGroups: flag })} /> ); @@ -185,4 +199,6 @@ class NewVisModal extends React.Component void; visType: VisType; uiSettings: IUiSettingsClient; savedObjects: SavedObjectsStart; + goBack: () => void; } export class SearchSelection extends React.Component { @@ -54,6 +56,7 @@ export class SearchSelection extends React.Component { + import('./new_vis_modal')); + export interface ShowNewVisModalParams { editorParams?: string[]; onClose?: () => void; @@ -66,20 +68,29 @@ export function showNewVisModal({ document.body.appendChild(container); const element = ( - + + + + } + > + + ); ReactDOM.render(element, container); diff --git a/src/plugins/visualizations/public/wizard/type_selection/new_vis_help.test.tsx b/src/plugins/visualizations/public/wizard/type_selection/new_vis_help.test.tsx deleted file mode 100644 index a5b6e8039ba6d5..00000000000000 --- a/src/plugins/visualizations/public/wizard/type_selection/new_vis_help.test.tsx +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import React from 'react'; -import { shallowWithIntl } from 'test_utils/enzyme_helpers'; -import { NewVisHelp } from './new_vis_help'; - -describe('NewVisHelp', () => { - it('should render as expected', () => { - expect( - shallowWithIntl( - {}} - /> - ) - ).toMatchInlineSnapshot(` - -

- -

-

- - Look at this fancy new thing!!! - -

- - Do it now! - -
- `); - }); -}); diff --git a/src/plugins/visualizations/public/wizard/type_selection/new_vis_help.tsx b/src/plugins/visualizations/public/wizard/type_selection/new_vis_help.tsx deleted file mode 100644 index 5b226a889408f0..00000000000000 --- a/src/plugins/visualizations/public/wizard/type_selection/new_vis_help.tsx +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { FormattedMessage } from '@kbn/i18n/react'; -import React, { Fragment } from 'react'; -import { EuiText, EuiButton } from '@elastic/eui'; -import { VisTypeAlias } from '../../vis_types'; - -interface Props { - promotedTypes: VisTypeAlias[]; - onPromotionClicked: (visType: VisTypeAlias) => void; -} - -export function NewVisHelp(props: Props) { - return ( - -

- -

- {props.promotedTypes.map((t) => ( - -

- {t.promotion!.description} -

- props.onPromotionClicked(t)} - fill - size="s" - iconType="popout" - iconSide="right" - > - {t.promotion!.buttonText} - -
- ))} -
- ); -} diff --git a/src/plugins/visualizations/public/wizard/type_selection/type_selection.tsx b/src/plugins/visualizations/public/wizard/type_selection/type_selection.tsx deleted file mode 100644 index 8c086ed132ae48..00000000000000 --- a/src/plugins/visualizations/public/wizard/type_selection/type_selection.tsx +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { orderBy } from 'lodash'; -import React, { ChangeEvent } from 'react'; - -import { - EuiFieldSearch, - EuiFlexGroup, - EuiFlexItem, - EuiKeyPadMenu, - EuiKeyPadMenuItem, - EuiModalHeader, - EuiModalHeaderTitle, - EuiScreenReaderOnly, - EuiSpacer, - EuiTitle, -} from '@elastic/eui'; - -import { memoizeLast } from '../../legacy/memoize'; -import { VisTypeAlias } from '../../vis_types/vis_type_alias_registry'; -import { NewVisHelp } from './new_vis_help'; -import { VisHelpText } from './vis_help_text'; -import { VisTypeIcon } from './vis_type_icon'; -import { VisType, TypesStart } from '../../vis_types'; - -interface VisTypeListEntry { - type: VisType | VisTypeAlias; - highlighted: boolean; -} - -interface TypeSelectionProps { - addBasePath: (path: string) => string; - onVisTypeSelected: (visType: VisType | VisTypeAlias) => void; - visTypesRegistry: TypesStart; - showExperimental: boolean; -} - -interface HighlightedType { - name: string; - title: string; - description?: string; - highlightMsg?: string; -} - -interface TypeSelectionState { - highlightedType: HighlightedType | null; - query: string; -} - -function isVisTypeAlias(type: VisType | VisTypeAlias): type is VisTypeAlias { - return 'aliasPath' in type; -} - -class TypeSelection extends React.Component { - public state: TypeSelectionState = { - highlightedType: null, - query: '', - }; - - private readonly getFilteredVisTypes = memoizeLast(this.filteredVisTypes); - - public render() { - const { query, highlightedType } = this.state; - const visTypes = this.getFilteredVisTypes(this.props.visTypesRegistry, query); - return ( - - - - - - -
- - - - - - - - - - {query && ( - type.highlighted).length, - }} - /> - )} - - - - {visTypes.map(this.renderVisType)} - - - - - - {highlightedType ? ( - - ) : ( - - -

- -

-
- - t.type) - .filter((t): t is VisTypeAlias => isVisTypeAlias(t) && Boolean(t.promotion))} - onPromotionClicked={this.props.onVisTypeSelected} - /> -
- )} -
-
-
-
- ); - } - - private filteredVisTypes(visTypes: TypesStart, query: string): VisTypeListEntry[] { - const types = visTypes.all().filter((type) => { - // Filter out all lab visualizations if lab mode is not enabled - if (!this.props.showExperimental && type.stage === 'experimental') { - return false; - } - - // Filter out hidden visualizations - if (type.hidden) { - return false; - } - - return true; - }); - - const allTypes = [...types, ...visTypes.getAliases()]; - - let entries: VisTypeListEntry[]; - if (!query) { - entries = allTypes.map((type) => ({ type, highlighted: false })); - } else { - const q = query.toLowerCase(); - entries = allTypes.map((type) => { - const matchesQuery = - type.name.toLowerCase().includes(q) || - type.title.toLowerCase().includes(q) || - (typeof type.description === 'string' && type.description.toLowerCase().includes(q)); - return { type, highlighted: matchesQuery }; - }); - } - - return orderBy( - entries, - ['highlighted', 'type.promotion', 'type.title'], - ['desc', 'asc', 'asc'] - ); - } - - private renderVisType = (visType: VisTypeListEntry) => { - let stage = {}; - let highlightMsg; - if (!isVisTypeAlias(visType.type) && visType.type.stage === 'experimental') { - stage = { - betaBadgeLabel: i18n.translate('visualizations.newVisWizard.experimentalTitle', { - defaultMessage: 'Experimental', - }), - betaBadgeTooltipContent: i18n.translate('visualizations.newVisWizard.experimentalTooltip', { - defaultMessage: - 'This visualization might be changed or removed in a future release and is not subject to the support SLA.', - }), - }; - highlightMsg = i18n.translate('visualizations.newVisWizard.experimentalDescription', { - defaultMessage: - 'This visualization is experimental. The design and implementation are less mature than stable visualizations and might be subject to change.', - }); - } else if (isVisTypeAlias(visType.type) && visType.type.stage === 'beta') { - const aliasDescription = i18n.translate('visualizations.newVisWizard.betaDescription', { - defaultMessage: - 'This visualization is in beta and is subject to change. The design and code is less mature than official GA features and is being provided as-is with no warranties. Beta features are not subject to the support SLA of official GA features', - }); - stage = { - betaBadgeLabel: i18n.translate('visualizations.newVisWizard.betaTitle', { - defaultMessage: 'Beta', - }), - betaBadgeTooltipContent: aliasDescription, - }; - highlightMsg = aliasDescription; - } - - const isDisabled = this.state.query !== '' && !visType.highlighted; - const onClick = () => this.props.onVisTypeSelected(visType.type); - - const highlightedType: HighlightedType = { - title: visType.type.title, - name: visType.type.name, - description: visType.type.description, - highlightMsg, - }; - - return ( - {visType.type.title}} - onClick={onClick} - onFocus={() => this.setHighlightType(highlightedType)} - onMouseEnter={() => this.setHighlightType(highlightedType)} - onMouseLeave={() => this.setHighlightType(null)} - onBlur={() => this.setHighlightType(null)} - className="visNewVisDialog__type" - data-test-subj={`visType-${visType.type.name}`} - data-vis-stage={!isVisTypeAlias(visType.type) ? visType.type.stage : 'alias'} - disabled={isDisabled} - aria-describedby={`visTypeDescription-${visType.type.name}`} - {...stage} - > - - - ); - }; - - private setHighlightType(highlightedType: HighlightedType | null) { - this.setState({ - highlightedType, - }); - } - - private onQueryChange = (ev: ChangeEvent) => { - this.setState({ - query: ev.target.value, - }); - }; -} - -export { TypeSelection }; diff --git a/test/functional/apps/dashboard/create_and_add_embeddables.js b/test/functional/apps/dashboard/create_and_add_embeddables.js index f5c2496a9a5aaf..c315828c594fa0 100644 --- a/test/functional/apps/dashboard/create_and_add_embeddables.js +++ b/test/functional/apps/dashboard/create_and_add_embeddables.js @@ -42,10 +42,11 @@ export default function ({ getService, getPageObjects }) { }); describe('add new visualization link', () => { - it('adds new visualiztion via the top nav link', async () => { + it('adds new visualization via the top nav link', async () => { const originalPanelCount = await PageObjects.dashboard.getPanelCount(); await PageObjects.dashboard.switchToEditMode(); await dashboardAddPanel.clickCreateNewLink(); + await PageObjects.visualize.clickAggBasedVisualizations(); await PageObjects.visualize.clickAreaChart(); await PageObjects.visualize.clickNewSearch(); await PageObjects.visualize.saveVisualizationExpectSuccess( @@ -63,6 +64,7 @@ export default function ({ getService, getPageObjects }) { const originalPanelCount = await PageObjects.dashboard.getPanelCount(); await dashboardAddPanel.ensureAddPanelIsShowing(); await dashboardAddPanel.clickAddNewEmbeddableLink('visualization'); + await PageObjects.visualize.clickAggBasedVisualizations(); await PageObjects.visualize.clickAreaChart(); await PageObjects.visualize.clickNewSearch(); await PageObjects.visualize.saveVisualizationExpectSuccess( diff --git a/test/functional/apps/dashboard/view_edit.js b/test/functional/apps/dashboard/view_edit.js index 589a46b7e9d08d..a6d81da131751a 100644 --- a/test/functional/apps/dashboard/view_edit.js +++ b/test/functional/apps/dashboard/view_edit.js @@ -134,6 +134,7 @@ export default function ({ getService, getPageObjects }) { await dashboardAddPanel.ensureAddPanelIsShowing(); await dashboardAddPanel.clickAddNewEmbeddableLink('visualization'); + await PageObjects.visualize.clickAggBasedVisualizations(); await PageObjects.visualize.clickAreaChart(); await PageObjects.visualize.clickNewSearch(); await PageObjects.visualize.saveVisualizationExpectSuccess('new viz panel', { diff --git a/test/functional/apps/discover/_discover.js b/test/functional/apps/discover/_discover.js index e597cc14654bcb..3c9996ca44ff8c 100644 --- a/test/functional/apps/discover/_discover.js +++ b/test/functional/apps/discover/_discover.js @@ -32,7 +32,8 @@ export default function ({ getService, getPageObjects }) { defaultIndex: 'logstash-*', }; - describe('discover test', function describeIndexTests() { + // Failing: See https://github.com/elastic/kibana/issues/82915 + describe.skip('discover test', function describeIndexTests() { before(async function () { log.debug('load kibana index with default index pattern'); await esArchiver.load('discover'); diff --git a/test/functional/apps/getting_started/_shakespeare.js b/test/functional/apps/getting_started/_shakespeare.js index 38ed3edc7deb55..a648dae99158d6 100644 --- a/test/functional/apps/getting_started/_shakespeare.js +++ b/test/functional/apps/getting_started/_shakespeare.js @@ -74,7 +74,7 @@ export default function ({ getService, getPageObjects }) { */ it('should create initial vertical bar chart', async function () { log.debug('create shakespeare vertical bar chart'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickVerticalBarChart(); await PageObjects.visualize.clickNewSearch('shakespeare'); await PageObjects.visChart.waitForVisualization(); diff --git a/test/functional/apps/visualize/_area_chart.js b/test/functional/apps/visualize/_area_chart.js index 9ac2160a359da1..b943e070e1768a 100644 --- a/test/functional/apps/visualize/_area_chart.js +++ b/test/functional/apps/visualize/_area_chart.js @@ -41,7 +41,7 @@ export default function ({ getService, getPageObjects }) { const initAreaChart = async () => { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickAreaChart'); await PageObjects.visualize.clickAreaChart(); log.debug('clickNewSearch'); @@ -390,7 +390,7 @@ export default function ({ getService, getPageObjects }) { const toTime = 'Jan 1, 2020 @ 00:00:00.000'; it('should render a yearly area with 12 svg paths', async () => { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickAreaChart'); await PageObjects.visualize.clickAreaChart(); log.debug('clickNewSearch'); @@ -413,7 +413,7 @@ export default function ({ getService, getPageObjects }) { }); it('should render monthly areas with 168 svg paths', async () => { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickAreaChart'); await PageObjects.visualize.clickAreaChart(); log.debug('clickNewSearch'); diff --git a/test/functional/apps/visualize/_chart_types.ts b/test/functional/apps/visualize/_chart_types.ts index ecb7e9630c2c65..4864fcbf3af095 100644 --- a/test/functional/apps/visualize/_chart_types.ts +++ b/test/functional/apps/visualize/_chart_types.ts @@ -33,10 +33,21 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewVisualization(); }); - it('should show the correct chart types', async function () { + it('should show the promoted vis types for the first step', async function () { + const expectedChartTypes = ['Custom visualization', 'Lens', 'Maps', 'TSVB']; + log.debug('oss= ' + isOss); + + // find all the chart types and make sure there all there + const chartTypes = (await PageObjects.visualize.getPromotedVisTypes()).sort(); + log.debug('returned chart types = ' + chartTypes); + log.debug('expected chart types = ' + expectedChartTypes); + expect(chartTypes).to.eql(expectedChartTypes); + }); + + it('should show the correct agg based chart types', async function () { + await PageObjects.visualize.clickAggBasedVisualizations(); let expectedChartTypes = [ 'Area', - 'Controls', 'Coordinate Map', 'Data Table', 'Gauge', @@ -44,18 +55,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'Heat Map', 'Horizontal Bar', 'Line', - 'Markdown', 'Metric', 'Pie', 'Region Map', - 'TSVB', 'Tag Cloud', 'Timelion', - 'Vega', 'Vertical Bar', ]; if (!isOss) { - expectedChartTypes.push('Maps', 'Lens'); expectedChartTypes = _.remove(expectedChartTypes, function (n) { return n !== 'Coordinate Map'; }); diff --git a/test/functional/apps/visualize/_data_table.js b/test/functional/apps/visualize/_data_table.js index a1389a69666ae1..bd7511d373b90e 100644 --- a/test/functional/apps/visualize/_data_table.js +++ b/test/functional/apps/visualize/_data_table.js @@ -32,7 +32,7 @@ export default function ({ getService, getPageObjects }) { before(async function () { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickDataTable'); await PageObjects.visualize.clickDataTable(); log.debug('clickNewSearch'); @@ -107,7 +107,7 @@ export default function ({ getService, getPageObjects }) { } // load a plain table - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); await PageObjects.timePicker.setDefaultAbsoluteRange(); @@ -152,7 +152,7 @@ export default function ({ getService, getPageObjects }) { }); it('should show correct data when using average pipeline aggregation', async () => { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); await PageObjects.timePicker.setDefaultAbsoluteRange(); @@ -167,7 +167,7 @@ export default function ({ getService, getPageObjects }) { }); it('should show correct data for a data table with date histogram', async () => { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); await PageObjects.timePicker.setDefaultAbsoluteRange(); @@ -189,7 +189,7 @@ export default function ({ getService, getPageObjects }) { }); it('should show correct data for a data table with date histogram', async () => { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); await PageObjects.timePicker.setDefaultAbsoluteRange(); @@ -224,7 +224,7 @@ export default function ({ getService, getPageObjects }) { }); it('should show correct data for a data table with top hits', async () => { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); await PageObjects.timePicker.setDefaultAbsoluteRange(); @@ -238,7 +238,7 @@ export default function ({ getService, getPageObjects }) { }); it('should show correct data for a data table with range agg', async () => { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); await PageObjects.timePicker.setDefaultAbsoluteRange(); @@ -257,7 +257,7 @@ export default function ({ getService, getPageObjects }) { describe('otherBucket', () => { before(async () => { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); await PageObjects.timePicker.setDefaultAbsoluteRange(); @@ -295,7 +295,7 @@ export default function ({ getService, getPageObjects }) { describe('metricsOnAllLevels', () => { before(async () => { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); await PageObjects.timePicker.setDefaultAbsoluteRange(); @@ -389,7 +389,7 @@ export default function ({ getService, getPageObjects }) { describe('split tables', () => { before(async () => { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); await PageObjects.timePicker.setDefaultAbsoluteRange(); diff --git a/test/functional/apps/visualize/_data_table_nontimeindex.js b/test/functional/apps/visualize/_data_table_nontimeindex.js index fd06257a91ff4f..f45e40970a57fd 100644 --- a/test/functional/apps/visualize/_data_table_nontimeindex.js +++ b/test/functional/apps/visualize/_data_table_nontimeindex.js @@ -32,7 +32,7 @@ export default function ({ getService, getPageObjects }) { before(async function () { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickDataTable'); await PageObjects.visualize.clickDataTable(); log.debug('clickNewSearch'); @@ -97,7 +97,7 @@ export default function ({ getService, getPageObjects }) { }); it('should show correct data when using average pipeline aggregation', async () => { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch( PageObjects.visualize.index.LOGSTASH_NON_TIME_BASED @@ -114,7 +114,7 @@ export default function ({ getService, getPageObjects }) { describe('data table with date histogram', async () => { before(async () => { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch( PageObjects.visualize.index.LOGSTASH_NON_TIME_BASED diff --git a/test/functional/apps/visualize/_data_table_notimeindex_filters.ts b/test/functional/apps/visualize/_data_table_notimeindex_filters.ts index 9fb6d793eb7d9d..cdcf08d2514e5d 100644 --- a/test/functional/apps/visualize/_data_table_notimeindex_filters.ts +++ b/test/functional/apps/visualize/_data_table_notimeindex_filters.ts @@ -40,7 +40,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { before(async function () { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickDataTable'); await PageObjects.visualize.clickDataTable(); log.debug('clickNewSearch'); diff --git a/test/functional/apps/visualize/_embedding_chart.js b/test/functional/apps/visualize/_embedding_chart.js index 5316bf51fd48c2..773bd63d8892f4 100644 --- a/test/functional/apps/visualize/_embedding_chart.js +++ b/test/functional/apps/visualize/_embedding_chart.js @@ -35,7 +35,7 @@ export default function ({ getService, getPageObjects }) { describe('embedding', () => { describe('a data table', () => { before(async function () { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); await PageObjects.timePicker.setDefaultAbsoluteRange(); diff --git a/test/functional/apps/visualize/_experimental_vis.js b/test/functional/apps/visualize/_experimental_vis.js index e87a36434b2314..c85d66eed12d21 100644 --- a/test/functional/apps/visualize/_experimental_vis.js +++ b/test/functional/apps/visualize/_experimental_vis.js @@ -27,7 +27,7 @@ export default ({ getService, getPageObjects }) => { describe('experimental visualizations', () => { beforeEach(async () => { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.waitForVisualizationSelectPage(); }); diff --git a/test/functional/apps/visualize/_gauge_chart.js b/test/functional/apps/visualize/_gauge_chart.js index 0f870b1fb545fb..06f5913aec8144 100644 --- a/test/functional/apps/visualize/_gauge_chart.js +++ b/test/functional/apps/visualize/_gauge_chart.js @@ -29,7 +29,7 @@ export default function ({ getService, getPageObjects }) { describe('gauge chart', function indexPatternCreation() { async function initGaugeVis() { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickGauge'); await PageObjects.visualize.clickGauge(); await PageObjects.visualize.clickNewSearch(); diff --git a/test/functional/apps/visualize/_heatmap_chart.js b/test/functional/apps/visualize/_heatmap_chart.js index 98a0104629c851..e48173c290372a 100644 --- a/test/functional/apps/visualize/_heatmap_chart.js +++ b/test/functional/apps/visualize/_heatmap_chart.js @@ -29,7 +29,7 @@ export default function ({ getService, getPageObjects }) { before(async function () { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickHeatmapChart'); await PageObjects.visualize.clickHeatmapChart(); await PageObjects.visualize.clickNewSearch(); diff --git a/test/functional/apps/visualize/_histogram_request_start.js b/test/functional/apps/visualize/_histogram_request_start.js index f6440cfbd76ffc..8489cffa805da2 100644 --- a/test/functional/apps/visualize/_histogram_request_start.js +++ b/test/functional/apps/visualize/_histogram_request_start.js @@ -33,7 +33,7 @@ export default function ({ getService, getPageObjects }) { describe('histogram agg onSearchRequestStart', function () { before(async function () { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickDataTable'); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); diff --git a/test/functional/apps/visualize/_inspector.js b/test/functional/apps/visualize/_inspector.js index 104184050e838b..426e61d9636ad8 100644 --- a/test/functional/apps/visualize/_inspector.js +++ b/test/functional/apps/visualize/_inspector.js @@ -25,7 +25,7 @@ export default function ({ getService, getPageObjects }) { describe('inspector', function describeIndexTests() { before(async function () { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickVerticalBarChart(); await PageObjects.visualize.clickNewSearch(); diff --git a/test/functional/apps/visualize/_line_chart.js b/test/functional/apps/visualize/_line_chart.js index 8dfc4d352b1331..8c6dbd3461a4f5 100644 --- a/test/functional/apps/visualize/_line_chart.js +++ b/test/functional/apps/visualize/_line_chart.js @@ -37,7 +37,7 @@ export default function ({ getService, getPageObjects }) { const initLineChart = async function () { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickLineChart'); await PageObjects.visualize.clickLineChart(); await PageObjects.visualize.clickNewSearch(); @@ -244,7 +244,7 @@ export default function ({ getService, getPageObjects }) { describe('pipeline aggregations', () => { before(async () => { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickLineChart'); await PageObjects.visualize.clickLineChart(); await PageObjects.visualize.clickNewSearch(); diff --git a/test/functional/apps/visualize/_linked_saved_searches.ts b/test/functional/apps/visualize/_linked_saved_searches.ts index 4151e0e9b471c5..a5a9c47d3d0102 100644 --- a/test/functional/apps/visualize/_linked_saved_searches.ts +++ b/test/functional/apps/visualize/_linked_saved_searches.ts @@ -47,7 +47,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should create a visualization from a saved search', async () => { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickSavedSearch(savedSearchName); await PageObjects.timePicker.setDefaultAbsoluteRange(); diff --git a/test/functional/apps/visualize/_metric_chart.js b/test/functional/apps/visualize/_metric_chart.js index e02dac11d9e982..483a0688d6acad 100644 --- a/test/functional/apps/visualize/_metric_chart.js +++ b/test/functional/apps/visualize/_metric_chart.js @@ -29,7 +29,7 @@ export default function ({ getService, getPageObjects }) { describe('metric chart', function () { before(async function () { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickMetric'); await PageObjects.visualize.clickMetric(); await PageObjects.visualize.clickNewSearch(); diff --git a/test/functional/apps/visualize/_pie_chart.js b/test/functional/apps/visualize/_pie_chart.js index b68a88c4f97f33..eef0f90005a436 100644 --- a/test/functional/apps/visualize/_pie_chart.js +++ b/test/functional/apps/visualize/_pie_chart.js @@ -37,7 +37,7 @@ export default function ({ getService, getPageObjects }) { const vizName1 = 'Visualization PieChart'; before(async function () { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickPieChart'); await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); @@ -94,7 +94,7 @@ export default function ({ getService, getPageObjects }) { it('should show other and missing bucket', async function () { const expectedTableData = ['win 8', 'win xp', 'win 7', 'ios', 'Missing', 'Other']; - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickPieChart'); await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); @@ -292,7 +292,7 @@ export default function ({ getService, getPageObjects }) { describe('empty time window', () => { it('should show no data message when no data on selected timerange', async function () { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickPieChart'); await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); @@ -321,7 +321,7 @@ export default function ({ getService, getPageObjects }) { describe('multi series slice', () => { before(async () => { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickPieChart'); await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); @@ -443,7 +443,7 @@ export default function ({ getService, getPageObjects }) { }); it('should still showing pie chart when a subseries have zero data', async function () { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickPieChart'); await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); @@ -471,7 +471,7 @@ export default function ({ getService, getPageObjects }) { describe('split chart', () => { before(async () => { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); await PageObjects.timePicker.setDefaultAbsoluteRange(); diff --git a/test/functional/apps/visualize/_point_series_options.js b/test/functional/apps/visualize/_point_series_options.js index c88670ee8b7414..a671cb82ab70fe 100644 --- a/test/functional/apps/visualize/_point_series_options.js +++ b/test/functional/apps/visualize/_point_series_options.js @@ -36,7 +36,7 @@ export default function ({ getService, getPageObjects }) { async function initChart() { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickLineChart'); await PageObjects.visualize.clickLineChart(); await PageObjects.visualize.clickNewSearch(); @@ -197,7 +197,7 @@ export default function ({ getService, getPageObjects }) { describe('show values on chart', () => { before(async () => { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickVerticalBarChart(); await PageObjects.visualize.clickNewSearch(); await PageObjects.timePicker.setDefaultAbsoluteRange(); @@ -232,7 +232,7 @@ export default function ({ getService, getPageObjects }) { const customLabel = 'myLabel'; const axisTitle = 'myTitle'; before(async function () { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickLineChart(); await PageObjects.visualize.clickNewSearch(); await PageObjects.visEditor.selectYAxisAggregation('Average', 'bytes', customLabel, 1); diff --git a/test/functional/apps/visualize/_region_map.js b/test/functional/apps/visualize/_region_map.js index f2fe1527c97c28..eee73d2fe76f9b 100644 --- a/test/functional/apps/visualize/_region_map.js +++ b/test/functional/apps/visualize/_region_map.js @@ -28,7 +28,7 @@ export default function ({ getService, getPageObjects }) { before(async function () { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickRegionMap'); await PageObjects.visualize.clickRegionMap(); await PageObjects.visualize.clickNewSearch(); diff --git a/test/functional/apps/visualize/_tag_cloud.js b/test/functional/apps/visualize/_tag_cloud.js index b5c575edb8a0a1..7b1671aaeb2f26 100644 --- a/test/functional/apps/visualize/_tag_cloud.js +++ b/test/functional/apps/visualize/_tag_cloud.js @@ -43,7 +43,7 @@ export default function ({ getService, getPageObjects }) { before(async function () { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickTagCloud'); await PageObjects.visualize.clickTagCloud(); await PageObjects.visualize.clickNewSearch(); diff --git a/test/functional/apps/visualize/_tile_map.js b/test/functional/apps/visualize/_tile_map.js index 56585ccd725d80..3ae72fe73a5fda 100644 --- a/test/functional/apps/visualize/_tile_map.js +++ b/test/functional/apps/visualize/_tile_map.js @@ -41,7 +41,7 @@ export default function ({ getService, getPageObjects }) { await browser.setWindowSize(1280, 1000); log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickTileMap'); await PageObjects.visualize.clickTileMap(); await PageObjects.visualize.clickNewSearch(); @@ -61,7 +61,7 @@ export default function ({ getService, getPageObjects }) { await browser.setWindowSize(1280, 1000); log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickTileMap'); await PageObjects.visualize.clickTileMap(); await PageObjects.visualize.clickNewSearch(); @@ -240,7 +240,7 @@ export default function ({ getService, getPageObjects }) { await browser.setWindowSize(1280, 1000); log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickTileMap'); await PageObjects.visualize.clickTileMap(); await PageObjects.visualize.clickNewSearch(); diff --git a/test/functional/apps/visualize/_vertical_bar_chart.js b/test/functional/apps/visualize/_vertical_bar_chart.js index ff0423eb531da9..5ecbf3f720ee67 100644 --- a/test/functional/apps/visualize/_vertical_bar_chart.js +++ b/test/functional/apps/visualize/_vertical_bar_chart.js @@ -32,7 +32,7 @@ export default function ({ getService, getPageObjects }) { const initBarChart = async () => { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickVerticalBarChart'); await PageObjects.visualize.clickVerticalBarChart(); await PageObjects.visualize.clickNewSearch(); @@ -64,7 +64,7 @@ export default function ({ getService, getPageObjects }) { }); it('should not filter out first label after rotation of the chart', async function () { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickVerticalBarChart(); await PageObjects.visualize.clickNewSearch(); await PageObjects.timePicker.setDefaultAbsoluteRange(); @@ -88,7 +88,7 @@ export default function ({ getService, getPageObjects }) { describe('bar charts range on x axis', () => { it('should individual bars for each configured range', async function () { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickVerticalBarChart(); await PageObjects.visualize.clickNewSearch(); await PageObjects.timePicker.setDefaultAbsoluteRange(); diff --git a/test/functional/apps/visualize/_vertical_bar_chart_nontimeindex.js b/test/functional/apps/visualize/_vertical_bar_chart_nontimeindex.js index f95781c9bbb337..7fb123f2e304ab 100644 --- a/test/functional/apps/visualize/_vertical_bar_chart_nontimeindex.js +++ b/test/functional/apps/visualize/_vertical_bar_chart_nontimeindex.js @@ -30,7 +30,7 @@ export default function ({ getService, getPageObjects }) { const initBarChart = async () => { log.debug('navigateToApp visualize'); - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickVerticalBarChart'); await PageObjects.visualize.clickVerticalBarChart(); await PageObjects.visualize.clickNewSearch( diff --git a/test/functional/page_objects/tile_map_page.ts b/test/functional/page_objects/tile_map_page.ts index 609e6ebddd50ac..7881c9b1f7155c 100644 --- a/test/functional/page_objects/tile_map_page.ts +++ b/test/functional/page_objects/tile_map_page.ts @@ -50,12 +50,14 @@ export function TileMapPageProvider({ getService, getPageObjects }: FtrProviderC await testSubjects.click('inspectorViewChooser'); await testSubjects.click('inspectorViewChooserRequests'); await testSubjects.click('inspectorRequestDetailRequest'); - return await testSubjects.getVisibleText('inspectorRequestBody'); + + return await inspector.getCodeEditorValue(); } public async getMapBounds(): Promise { const request = await this.getVisualizationRequest(); const requestObject = JSON.parse(request); + return requestObject.aggs.filter_agg.filter.geo_bounding_box['geo.coordinates']; } diff --git a/test/functional/page_objects/visualize_page.ts b/test/functional/page_objects/visualize_page.ts index 9619c81370cd8d..b58acd0bd90592 100644 --- a/test/functional/page_objects/visualize_page.ts +++ b/test/functional/page_objects/visualize_page.ts @@ -47,6 +47,14 @@ export function VisualizePageProvider({ getService, getPageObjects }: FtrProvide await listingTable.clickNewButton('createVisualizationPromptButton'); } + public async clickAggBasedVisualizations() { + await testSubjects.click('visGroupAggBasedExploreLink'); + } + + public async goBackToGroups() { + await testSubjects.click('goBackLink'); + } + public async createVisualizationPromptButton() { await testSubjects.click('createVisualizationPromptButton'); } @@ -59,6 +67,21 @@ export function VisualizePageProvider({ getService, getPageObjects }: FtrProvide .map((chart) => $(chart).findTestSubject('visTypeTitle').text().trim()); } + public async getPromotedVisTypes() { + const chartTypeField = await testSubjects.find('visNewDialogGroups'); + const $ = await chartTypeField.parseDomContent(); + const promotedVisTypes: string[] = []; + $('button') + .toArray() + .forEach((chart) => { + const title = $(chart).findTestSubject('visTypeTitle').text().trim(); + if (title) { + promotedVisTypes.push(title); + } + }); + return promotedVisTypes; + } + public async waitForVisualizationSelectPage() { await retry.try(async () => { const visualizeSelectTypePage = await testSubjects.find('visNewDialogTypes'); @@ -68,10 +91,27 @@ export function VisualizePageProvider({ getService, getPageObjects }: FtrProvide }); } + public async waitForGroupsSelectPage() { + await retry.try(async () => { + const visualizeSelectGroupStep = await testSubjects.find('visNewDialogGroups'); + if (!(await visualizeSelectGroupStep.isDisplayed())) { + throw new Error('wait for vis groups select step'); + } + }); + } + public async navigateToNewVisualization() { await common.navigateToApp('visualize'); await header.waitUntilLoadingHasFinished(); await this.clickNewVisualization(); + await this.waitForGroupsSelectPage(); + } + + public async navigateToNewAggBasedVisualization() { + await common.navigateToApp('visualize'); + await header.waitUntilLoadingHasFinished(); + await this.clickNewVisualization(); + await this.clickAggBasedVisualizations(); await this.waitForVisualizationSelectPage(); } diff --git a/test/functional/services/dashboard/visualizations.ts b/test/functional/services/dashboard/visualizations.ts index a5c16010d3ebaa..b35ef1e8f2f9a9 100644 --- a/test/functional/services/dashboard/visualizations.ts +++ b/test/functional/services/dashboard/visualizations.ts @@ -147,6 +147,7 @@ export function DashboardVisualizationProvider({ getService, getPageObjects }: F await PageObjects.dashboard.switchToEditMode(); } await this.ensureNewVisualizationDialogIsShowing(); + await PageObjects.visualize.clickAggBasedVisualizations(); await PageObjects.visualize.clickMetric(); await find.clickByCssSelector('li.euiListGroupItem:nth-of-type(2)'); await testSubjects.exists('visualizeSaveButton'); diff --git a/test/functional/services/inspector.ts b/test/functional/services/inspector.ts index 1c0bf7ad46df15..e256cf14541a7e 100644 --- a/test/functional/services/inspector.ts +++ b/test/functional/services/inspector.ts @@ -23,6 +23,7 @@ import { FtrProviderContext } from '../ftr_provider_context'; export function InspectorProvider({ getService }: FtrProviderContext) { const log = getService('log'); const retry = getService('retry'); + const browser = getService('browser'); const renderable = getService('renderable'); const flyout = getService('flyout'); const testSubjects = getService('testSubjects'); @@ -245,6 +246,18 @@ export function InspectorProvider({ getService }: FtrProviderContext) { public getOpenRequestDetailResponseButton() { return testSubjects.find('inspectorRequestDetailResponse'); } + + public async getCodeEditorValue() { + let request: string = ''; + + await retry.try(async () => { + request = await browser.execute( + () => (window as any).monaco.editor.getModels()[0].getValue() as string + ); + }); + + return request; + } } return new Inspector(); diff --git a/test/plugin_functional/test_suites/custom_visualizations/self_changing_vis.js b/test/plugin_functional/test_suites/custom_visualizations/self_changing_vis.js index 0846780f75ff61..1971754d5304e5 100644 --- a/test/plugin_functional/test_suites/custom_visualizations/self_changing_vis.js +++ b/test/plugin_functional/test_suites/custom_visualizations/self_changing_vis.js @@ -30,7 +30,7 @@ export default function ({ getService, getPageObjects }) { describe('self changing vis', function describeIndexTests() { before(async () => { - await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickVisType('self_changing_vis'); }); diff --git a/x-pack/examples/alerting_example/public/alert_types/always_firing.tsx b/x-pack/examples/alerting_example/public/alert_types/always_firing.tsx index 9c420f4425d04e..a5d158fca836b3 100644 --- a/x-pack/examples/alerting_example/public/alert_types/always_firing.tsx +++ b/x-pack/examples/alerting_example/public/alert_types/always_firing.tsx @@ -22,6 +22,7 @@ export function getAlertType(): AlertTypeModel { name: 'Always Fires', description: 'Alert when called', iconClass: 'bolt', + documentationUrl: null, alertParamsExpression: AlwaysFiringExpression, validate: (alertParams: AlwaysFiringParamsProps['alertParams']) => { const { instances } = alertParams; diff --git a/x-pack/examples/alerting_example/public/alert_types/astros.tsx b/x-pack/examples/alerting_example/public/alert_types/astros.tsx index e394f6aecaa01e..54f989b93e22f4 100644 --- a/x-pack/examples/alerting_example/public/alert_types/astros.tsx +++ b/x-pack/examples/alerting_example/public/alert_types/astros.tsx @@ -47,6 +47,7 @@ export function getAlertType(): AlertTypeModel { name: 'People Are In Space Right Now', description: 'Alert when people are in space right now', iconClass: 'globe', + documentationUrl: null, alertParamsExpression: PeopleinSpaceExpression, validate: (alertParams: PeopleinSpaceParamsProps['alertParams']) => { const { outerSpaceCapacity, craft, op } = alertParams; diff --git a/x-pack/plugins/alerts/common/alert.ts b/x-pack/plugins/alerts/common/alert.ts index 79e6bb8f2cbbaf..97a9a58400e385 100644 --- a/x-pack/plugins/alerts/common/alert.ts +++ b/x-pack/plugins/alerts/common/alert.ts @@ -20,13 +20,12 @@ export interface IntervalSchedule extends SavedObjectAttributes { export const AlertExecutionStatusValues = ['ok', 'active', 'error', 'pending', 'unknown'] as const; export type AlertExecutionStatuses = typeof AlertExecutionStatusValues[number]; -export const AlertExecutionStatusErrorReasonValues = [ - 'read', - 'decrypt', - 'execute', - 'unknown', -] as const; -export type AlertExecutionStatusErrorReasons = typeof AlertExecutionStatusErrorReasonValues[number]; +export enum AlertExecutionStatusErrorReasons { + Read = 'read', + Decrypt = 'decrypt', + Execute = 'execute', + Unknown = 'unknown', +} export interface AlertExecutionStatus { status: AlertExecutionStatuses; @@ -74,3 +73,24 @@ export interface Alert { } export type SanitizedAlert = Omit; + +export enum HealthStatus { + OK = 'ok', + Warning = 'warn', + Error = 'error', +} + +export interface AlertsHealth { + decryptionHealth: { + status: HealthStatus; + timestamp: string; + }; + executionHealth: { + status: HealthStatus; + timestamp: string; + }; + readHealth: { + status: HealthStatus; + timestamp: string; + }; +} diff --git a/x-pack/plugins/alerts/common/alert_instance_summary.ts b/x-pack/plugins/alerts/common/alert_instance_summary.ts index 08c3b2fc2c241c..1aa183a141eab6 100644 --- a/x-pack/plugins/alerts/common/alert_instance_summary.ts +++ b/x-pack/plugins/alerts/common/alert_instance_summary.ts @@ -27,5 +27,6 @@ export interface AlertInstanceSummary { export interface AlertInstanceStatus { status: AlertInstanceStatusValues; muted: boolean; + actionGroupId?: string; activeStartDate?: string; } diff --git a/x-pack/plugins/alerts/common/index.ts b/x-pack/plugins/alerts/common/index.ts index ab71f77a049f66..65aeec840da7e2 100644 --- a/x-pack/plugins/alerts/common/index.ts +++ b/x-pack/plugins/alerts/common/index.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { AlertsHealth } from './alert'; + export * from './alert'; export * from './alert_type'; export * from './alert_instance'; @@ -19,6 +21,7 @@ export interface ActionGroup { export interface AlertingFrameworkHealth { isSufficientlySecure: boolean; hasPermanentEncryptionKey: boolean; + alertingFrameworkHeath: AlertsHealth; } export const BASE_ALERT_API_PATH = '/api/alerts'; diff --git a/x-pack/plugins/alerts/server/alerts_client/tests/get_alert_instance_summary.test.ts b/x-pack/plugins/alerts/server/alerts_client/tests/get_alert_instance_summary.test.ts index a53e49337f3857..9cb2a33222d23d 100644 --- a/x-pack/plugins/alerts/server/alerts_client/tests/get_alert_instance_summary.test.ts +++ b/x-pack/plugins/alerts/server/alerts_client/tests/get_alert_instance_summary.test.ts @@ -118,12 +118,12 @@ describe('getAlertInstanceSummary()', () => { .addExecute() .addNewInstance('instance-currently-active') .addNewInstance('instance-previously-active') - .addActiveInstance('instance-currently-active') - .addActiveInstance('instance-previously-active') + .addActiveInstance('instance-currently-active', 'action group A') + .addActiveInstance('instance-previously-active', 'action group B') .advanceTime(10000) .addExecute() .addResolvedInstance('instance-previously-active') - .addActiveInstance('instance-currently-active') + .addActiveInstance('instance-currently-active', 'action group A') .getEvents(); const eventsResult = { ...AlertInstanceSummaryFindEventsResult, @@ -144,16 +144,19 @@ describe('getAlertInstanceSummary()', () => { "id": "1", "instances": Object { "instance-currently-active": Object { + "actionGroupId": "action group A", "activeStartDate": "2019-02-12T21:01:22.479Z", "muted": false, "status": "Active", }, "instance-muted-no-activity": Object { + "actionGroupId": undefined, "activeStartDate": undefined, "muted": true, "status": "OK", }, "instance-previously-active": Object { + "actionGroupId": undefined, "activeStartDate": undefined, "muted": false, "status": "OK", diff --git a/x-pack/plugins/alerts/server/config.test.ts b/x-pack/plugins/alerts/server/config.test.ts new file mode 100644 index 00000000000000..93aa3c38a04602 --- /dev/null +++ b/x-pack/plugins/alerts/server/config.test.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { configSchema } from './config'; + +describe('config validation', () => { + test('alerts defaults', () => { + const config: Record = {}; + expect(configSchema.validate(config)).toMatchInlineSnapshot(` + Object { + "healthCheck": Object { + "interval": "60m", + }, + } + `); + }); +}); diff --git a/x-pack/plugins/alerts/server/config.ts b/x-pack/plugins/alerts/server/config.ts new file mode 100644 index 00000000000000..a6d2196a407b5e --- /dev/null +++ b/x-pack/plugins/alerts/server/config.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; +import { validateDurationSchema } from './lib'; + +export const configSchema = schema.object({ + healthCheck: schema.object({ + interval: schema.string({ validate: validateDurationSchema, defaultValue: '60m' }), + }), +}); + +export type AlertsConfig = TypeOf; diff --git a/x-pack/plugins/alerts/server/health/get_health.test.ts b/x-pack/plugins/alerts/server/health/get_health.test.ts new file mode 100644 index 00000000000000..34517a89f04d92 --- /dev/null +++ b/x-pack/plugins/alerts/server/health/get_health.test.ts @@ -0,0 +1,221 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { savedObjectsRepositoryMock } from '../../../../../src/core/server/mocks'; +import { AlertExecutionStatusErrorReasons, HealthStatus } from '../types'; +import { getHealth } from './get_health'; + +const savedObjectsRepository = savedObjectsRepositoryMock.create(); + +describe('getHealth()', () => { + test('return true if some of alerts has a decryption error', async () => { + const lastExecutionDateError = new Date().toISOString(); + const lastExecutionDate = new Date().toISOString(); + savedObjectsRepository.find.mockResolvedValueOnce({ + total: 1, + per_page: 1, + page: 1, + saved_objects: [ + { + id: '1', + type: 'alert', + attributes: { + alertTypeId: 'myType', + schedule: { interval: '10s' }, + params: { + bar: true, + }, + createdAt: new Date().toISOString(), + actions: [ + { + group: 'default', + actionRef: 'action_0', + params: { + foo: true, + }, + }, + ], + executionStatus: { + status: 'error', + lastExecutionDate: lastExecutionDateError, + error: { + reason: AlertExecutionStatusErrorReasons.Decrypt, + message: 'Failed decrypt', + }, + }, + }, + score: 1, + references: [ + { + name: 'action_0', + type: 'action', + id: '1', + }, + ], + }, + ], + }); + savedObjectsRepository.find.mockResolvedValueOnce({ + total: 0, + per_page: 10, + page: 1, + saved_objects: [], + }); + + savedObjectsRepository.find.mockResolvedValueOnce({ + total: 0, + per_page: 10, + page: 1, + saved_objects: [], + }); + + savedObjectsRepository.find.mockResolvedValueOnce({ + total: 1, + per_page: 1, + page: 1, + saved_objects: [ + { + id: '2', + type: 'alert', + attributes: { + alertTypeId: 'myType', + schedule: { interval: '1s' }, + params: { + bar: true, + }, + createdAt: new Date().toISOString(), + actions: [], + executionStatus: { + status: 'ok', + lastExecutionDate, + }, + }, + score: 1, + references: [], + }, + ], + }); + const result = await getHealth(savedObjectsRepository); + expect(result).toStrictEqual({ + executionHealth: { + status: HealthStatus.OK, + timestamp: lastExecutionDate, + }, + readHealth: { + status: HealthStatus.OK, + timestamp: lastExecutionDate, + }, + decryptionHealth: { + status: HealthStatus.Warning, + timestamp: lastExecutionDateError, + }, + }); + expect(savedObjectsRepository.find).toHaveBeenCalledTimes(4); + }); + + test('return false if no alerts with a decryption error', async () => { + const lastExecutionDateError = new Date().toISOString(); + const lastExecutionDate = new Date().toISOString(); + savedObjectsRepository.find.mockResolvedValueOnce({ + total: 0, + per_page: 10, + page: 1, + saved_objects: [], + }); + + savedObjectsRepository.find.mockResolvedValueOnce({ + total: 1, + per_page: 1, + page: 1, + saved_objects: [ + { + id: '1', + type: 'alert', + attributes: { + alertTypeId: 'myType', + schedule: { interval: '10s' }, + params: { + bar: true, + }, + createdAt: new Date().toISOString(), + actions: [ + { + group: 'default', + actionRef: 'action_0', + params: { + foo: true, + }, + }, + ], + executionStatus: { + status: 'error', + lastExecutionDate: lastExecutionDateError, + error: { + reason: AlertExecutionStatusErrorReasons.Execute, + message: 'Failed', + }, + }, + }, + score: 1, + references: [ + { + name: 'action_0', + type: 'action', + id: '1', + }, + ], + }, + ], + }); + savedObjectsRepository.find.mockResolvedValueOnce({ + total: 0, + per_page: 10, + page: 1, + saved_objects: [], + }); + + savedObjectsRepository.find.mockResolvedValueOnce({ + total: 1, + per_page: 1, + page: 1, + saved_objects: [ + { + id: '2', + type: 'alert', + attributes: { + alertTypeId: 'myType', + schedule: { interval: '1s' }, + params: { + bar: true, + }, + createdAt: new Date().toISOString(), + actions: [], + executionStatus: { + status: 'ok', + lastExecutionDate, + }, + }, + score: 1, + references: [], + }, + ], + }); + const result = await getHealth(savedObjectsRepository); + expect(result).toStrictEqual({ + executionHealth: { + status: HealthStatus.Warning, + timestamp: lastExecutionDateError, + }, + readHealth: { + status: HealthStatus.OK, + timestamp: lastExecutionDate, + }, + decryptionHealth: { + status: HealthStatus.OK, + timestamp: lastExecutionDate, + }, + }); + }); +}); diff --git a/x-pack/plugins/alerts/server/health/get_health.ts b/x-pack/plugins/alerts/server/health/get_health.ts new file mode 100644 index 00000000000000..b7b4582aa8d109 --- /dev/null +++ b/x-pack/plugins/alerts/server/health/get_health.ts @@ -0,0 +1,97 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { ISavedObjectsRepository } from 'src/core/server'; +import { AlertsHealth, HealthStatus, RawAlert, AlertExecutionStatusErrorReasons } from '../types'; + +export const getHealth = async ( + internalSavedObjectsRepository: ISavedObjectsRepository +): Promise => { + const healthStatuses = { + decryptionHealth: { + status: HealthStatus.OK, + timestamp: '', + }, + executionHealth: { + status: HealthStatus.OK, + timestamp: '', + }, + readHealth: { + status: HealthStatus.OK, + timestamp: '', + }, + }; + + const { saved_objects: decryptErrorData } = await internalSavedObjectsRepository.find({ + filter: `alert.attributes.executionStatus.status:error and alert.attributes.executionStatus.error.reason:${AlertExecutionStatusErrorReasons.Decrypt}`, + fields: ['executionStatus'], + type: 'alert', + sortField: 'executionStatus.lastExecutionDate', + sortOrder: 'desc', + page: 1, + perPage: 1, + }); + + if (decryptErrorData.length > 0) { + healthStatuses.decryptionHealth = { + status: HealthStatus.Warning, + timestamp: decryptErrorData[0].attributes.executionStatus.lastExecutionDate, + }; + } + + const { saved_objects: executeErrorData } = await internalSavedObjectsRepository.find({ + filter: `alert.attributes.executionStatus.status:error and alert.attributes.executionStatus.error.reason:${AlertExecutionStatusErrorReasons.Execute}`, + fields: ['executionStatus'], + type: 'alert', + sortField: 'executionStatus.lastExecutionDate', + sortOrder: 'desc', + page: 1, + perPage: 1, + }); + + if (executeErrorData.length > 0) { + healthStatuses.executionHealth = { + status: HealthStatus.Warning, + timestamp: executeErrorData[0].attributes.executionStatus.lastExecutionDate, + }; + } + + const { saved_objects: readErrorData } = await internalSavedObjectsRepository.find({ + filter: `alert.attributes.executionStatus.status:error and alert.attributes.executionStatus.error.reason:${AlertExecutionStatusErrorReasons.Read}`, + fields: ['executionStatus'], + type: 'alert', + sortField: 'executionStatus.lastExecutionDate', + sortOrder: 'desc', + page: 1, + perPage: 1, + }); + + if (readErrorData.length > 0) { + healthStatuses.readHealth = { + status: HealthStatus.Warning, + timestamp: readErrorData[0].attributes.executionStatus.lastExecutionDate, + }; + } + + const { saved_objects: noErrorData } = await internalSavedObjectsRepository.find({ + filter: 'not alert.attributes.executionStatus.status:error', + fields: ['executionStatus'], + type: 'alert', + sortField: 'executionStatus.lastExecutionDate', + sortOrder: 'desc', + }); + const lastExecutionDate = + noErrorData.length > 0 + ? noErrorData[0].attributes.executionStatus.lastExecutionDate + : new Date().toISOString(); + + for (const [, statusItem] of Object.entries(healthStatuses)) { + if (statusItem.status === HealthStatus.OK) { + statusItem.timestamp = lastExecutionDate; + } + } + + return healthStatuses; +}; diff --git a/x-pack/plugins/alerts/server/health/get_state.test.ts b/x-pack/plugins/alerts/server/health/get_state.test.ts new file mode 100644 index 00000000000000..86981c486da0f5 --- /dev/null +++ b/x-pack/plugins/alerts/server/health/get_state.test.ts @@ -0,0 +1,75 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { taskManagerMock } from '../../../task_manager/server/mocks'; +import { getHealthStatusStream } from '.'; +import { TaskStatus } from '../../../task_manager/server'; +import { HealthStatus } from '../types'; + +describe('getHealthStatusStream()', () => { + const mockTaskManager = taskManagerMock.createStart(); + + it('should return an object with the "unavailable" level and proper summary of "Alerting framework is unhealthy"', async () => { + mockTaskManager.get.mockReturnValue( + new Promise((_resolve, _reject) => { + return { + id: 'test', + attempts: 0, + status: TaskStatus.Running, + version: '123', + runAt: new Date(), + scheduledAt: new Date(), + startedAt: new Date(), + retryAt: new Date(Date.now() + 5 * 60 * 1000), + state: { + runs: 1, + health_status: HealthStatus.Warning, + }, + taskType: 'alerting:alerting_health_check', + params: { + alertId: '1', + }, + ownerId: null, + }; + }) + ); + getHealthStatusStream(mockTaskManager).subscribe( + (val: { level: Readonly; summary: string }) => { + expect(val.level).toBe(false); + } + ); + }); + + it('should return an object with the "available" level and proper summary of "Alerting framework is healthy"', async () => { + mockTaskManager.get.mockReturnValue( + new Promise((_resolve, _reject) => { + return { + id: 'test', + attempts: 0, + status: TaskStatus.Running, + version: '123', + runAt: new Date(), + scheduledAt: new Date(), + startedAt: new Date(), + retryAt: new Date(Date.now() + 5 * 60 * 1000), + state: { + runs: 1, + health_status: HealthStatus.OK, + }, + taskType: 'alerting:alerting_health_check', + params: { + alertId: '1', + }, + ownerId: null, + }; + }) + ); + getHealthStatusStream(mockTaskManager).subscribe( + (val: { level: Readonly; summary: string }) => { + expect(val.level).toBe(true); + } + ); + }); +}); diff --git a/x-pack/plugins/alerts/server/health/get_state.ts b/x-pack/plugins/alerts/server/health/get_state.ts new file mode 100644 index 00000000000000..476456ecad88ae --- /dev/null +++ b/x-pack/plugins/alerts/server/health/get_state.ts @@ -0,0 +1,73 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; +import { interval, Observable } from 'rxjs'; +import { catchError, switchMap } from 'rxjs/operators'; +import { ServiceStatus, ServiceStatusLevels } from '../../../../../src/core/server'; +import { TaskManagerStartContract } from '../../../task_manager/server'; +import { HEALTH_TASK_ID } from './task'; +import { HealthStatus } from '../types'; + +async function getLatestTaskState(taskManager: TaskManagerStartContract) { + try { + const result = await taskManager.get(HEALTH_TASK_ID); + return result; + } catch (err) { + const errMessage = err && err.message ? err.message : err.toString(); + if (!errMessage.includes('NotInitialized')) { + throw err; + } + } + + return null; +} + +const LEVEL_SUMMARY = { + [ServiceStatusLevels.available.toString()]: i18n.translate( + 'xpack.alerts.server.healthStatus.available', + { + defaultMessage: 'Alerting framework is available', + } + ), + [ServiceStatusLevels.degraded.toString()]: i18n.translate( + 'xpack.alerts.server.healthStatus.degraded', + { + defaultMessage: 'Alerting framework is degraded', + } + ), + [ServiceStatusLevels.unavailable.toString()]: i18n.translate( + 'xpack.alerts.server.healthStatus.unavailable', + { + defaultMessage: 'Alerting framework is unavailable', + } + ), +}; + +export const getHealthStatusStream = ( + taskManager: TaskManagerStartContract +): Observable> => { + return interval(60000 * 5).pipe( + switchMap(async () => { + const doc = await getLatestTaskState(taskManager); + const level = + doc?.state?.health_status === HealthStatus.OK + ? ServiceStatusLevels.available + : doc?.state?.health_status === HealthStatus.Warning + ? ServiceStatusLevels.degraded + : ServiceStatusLevels.unavailable; + return { + level, + summary: LEVEL_SUMMARY[level.toString()], + }; + }), + catchError(async (error) => ({ + level: ServiceStatusLevels.unavailable, + summary: LEVEL_SUMMARY[ServiceStatusLevels.unavailable.toString()], + meta: { error }, + })) + ); +}; diff --git a/x-pack/plugins/alerts/server/health/index.ts b/x-pack/plugins/alerts/server/health/index.ts new file mode 100644 index 00000000000000..730c4596aa550e --- /dev/null +++ b/x-pack/plugins/alerts/server/health/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { getHealthStatusStream } from './get_state'; +export { scheduleAlertingHealthCheck, initializeAlertingHealth } from './task'; diff --git a/x-pack/plugins/alerts/server/health/task.ts b/x-pack/plugins/alerts/server/health/task.ts new file mode 100644 index 00000000000000..6ea01a1083c130 --- /dev/null +++ b/x-pack/plugins/alerts/server/health/task.ts @@ -0,0 +1,94 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { CoreStart, Logger } from 'kibana/server'; +import { + RunContext, + TaskManagerSetupContract, + TaskManagerStartContract, +} from '../../../task_manager/server'; +import { AlertsConfig } from '../config'; +import { AlertingPluginsStart } from '../plugin'; +import { HealthStatus } from '../types'; +import { getHealth } from './get_health'; + +export const HEALTH_TASK_TYPE = 'alerting_health_check'; + +export const HEALTH_TASK_ID = `Alerting-${HEALTH_TASK_TYPE}`; + +export function initializeAlertingHealth( + logger: Logger, + taskManager: TaskManagerSetupContract, + coreStartServices: Promise<[CoreStart, AlertingPluginsStart, unknown]> +) { + registerAlertingHealthCheckTask(logger, taskManager, coreStartServices); +} + +export async function scheduleAlertingHealthCheck( + logger: Logger, + config: Promise, + taskManager: TaskManagerStartContract +) { + try { + const interval = (await config).healthCheck.interval; + await taskManager.ensureScheduled({ + id: HEALTH_TASK_ID, + taskType: HEALTH_TASK_TYPE, + schedule: { + interval, + }, + state: {}, + params: {}, + }); + } catch (e) { + logger.debug(`Error scheduling task, received ${e.message}`); + } +} + +function registerAlertingHealthCheckTask( + logger: Logger, + taskManager: TaskManagerSetupContract, + coreStartServices: Promise<[CoreStart, AlertingPluginsStart, unknown]> +) { + taskManager.registerTaskDefinitions({ + [HEALTH_TASK_TYPE]: { + title: 'Alerting framework health check task', + createTaskRunner: healthCheckTaskRunner(logger, coreStartServices), + }, + }); +} + +export function healthCheckTaskRunner( + logger: Logger, + coreStartServices: Promise<[CoreStart, AlertingPluginsStart, unknown]> +) { + return ({ taskInstance }: RunContext) => { + const { state } = taskInstance; + return { + async run() { + try { + const alertingHealthStatus = await getHealth( + (await coreStartServices)[0].savedObjects.createInternalRepository(['alert']) + ); + return { + state: { + runs: (state.runs || 0) + 1, + health_status: alertingHealthStatus.decryptionHealth.status, + }, + }; + } catch (errMsg) { + logger.warn(`Error executing alerting health check task: ${errMsg}`); + return { + state: { + runs: (state.runs || 0) + 1, + health_status: HealthStatus.Error, + }, + }; + } + }, + }; + }; +} diff --git a/x-pack/plugins/alerts/server/index.ts b/x-pack/plugins/alerts/server/index.ts index 1e442c5196cf20..64e585da5c6544 100644 --- a/x-pack/plugins/alerts/server/index.ts +++ b/x-pack/plugins/alerts/server/index.ts @@ -5,8 +5,10 @@ */ import type { PublicMethodsOf } from '@kbn/utility-types'; import { AlertsClient as AlertsClientClass } from './alerts_client'; -import { PluginInitializerContext } from '../../../../src/core/server'; +import { PluginConfigDescriptor, PluginInitializerContext } from '../../../../src/core/server'; import { AlertingPlugin } from './plugin'; +import { configSchema } from './config'; +import { AlertsConfigType } from './types'; export type AlertsClient = PublicMethodsOf; @@ -30,3 +32,7 @@ export { AlertInstance } from './alert_instance'; export { parseDuration } from './lib'; export const plugin = (initContext: PluginInitializerContext) => new AlertingPlugin(initContext); + +export const config: PluginConfigDescriptor = { + schema: configSchema, +}; diff --git a/x-pack/plugins/alerts/server/lib/alert_execution_status.test.ts b/x-pack/plugins/alerts/server/lib/alert_execution_status.test.ts index 3372d19cd40901..bb24ab034d0dde 100644 --- a/x-pack/plugins/alerts/server/lib/alert_execution_status.test.ts +++ b/x-pack/plugins/alerts/server/lib/alert_execution_status.test.ts @@ -57,7 +57,9 @@ describe('AlertExecutionStatus', () => { }); test('error with a reason', () => { - const status = executionStatusFromError(new ErrorWithReason('execute', new Error('hoo!'))); + const status = executionStatusFromError( + new ErrorWithReason(AlertExecutionStatusErrorReasons.Execute, new Error('hoo!')) + ); expect(status.status).toBe('error'); expect(status.error).toMatchInlineSnapshot(` Object { @@ -71,7 +73,7 @@ describe('AlertExecutionStatus', () => { describe('alertExecutionStatusToRaw()', () => { const date = new Date('2020-09-03T16:26:58Z'); const status = 'ok'; - const reason: AlertExecutionStatusErrorReasons = 'decrypt'; + const reason = AlertExecutionStatusErrorReasons.Decrypt; const error = { reason, message: 'wops' }; test('status without an error', () => { @@ -102,7 +104,7 @@ describe('AlertExecutionStatus', () => { describe('alertExecutionStatusFromRaw()', () => { const date = new Date('2020-09-03T16:26:58Z').toISOString(); const status = 'active'; - const reason: AlertExecutionStatusErrorReasons = 'execute'; + const reason = AlertExecutionStatusErrorReasons.Execute; const error = { reason, message: 'wops' }; test('no input', () => { diff --git a/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.test.ts b/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.test.ts index 566a1770c0658e..f9e4a2908d6ce3 100644 --- a/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.test.ts +++ b/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.test.ts @@ -104,11 +104,13 @@ describe('alertInstanceSummaryFromEventLog', () => { Object { "instances": Object { "instance-1": Object { + "actionGroupId": undefined, "activeStartDate": undefined, "muted": true, "status": "OK", }, "instance-2": Object { + "actionGroupId": undefined, "activeStartDate": undefined, "muted": true, "status": "OK", @@ -184,7 +186,7 @@ describe('alertInstanceSummaryFromEventLog', () => { const events = eventsFactory .addExecute() .addNewInstance('instance-1') - .addActiveInstance('instance-1') + .addActiveInstance('instance-1', 'action group A') .advanceTime(10000) .addExecute() .addResolvedInstance('instance-1') @@ -202,6 +204,7 @@ describe('alertInstanceSummaryFromEventLog', () => { Object { "instances": Object { "instance-1": Object { + "actionGroupId": undefined, "activeStartDate": undefined, "muted": false, "status": "OK", @@ -218,7 +221,7 @@ describe('alertInstanceSummaryFromEventLog', () => { const eventsFactory = new EventsFactory(); const events = eventsFactory .addExecute() - .addActiveInstance('instance-1') + .addActiveInstance('instance-1', 'action group A') .advanceTime(10000) .addExecute() .addResolvedInstance('instance-1') @@ -236,6 +239,7 @@ describe('alertInstanceSummaryFromEventLog', () => { Object { "instances": Object { "instance-1": Object { + "actionGroupId": undefined, "activeStartDate": undefined, "muted": false, "status": "OK", @@ -253,10 +257,10 @@ describe('alertInstanceSummaryFromEventLog', () => { const events = eventsFactory .addExecute() .addNewInstance('instance-1') - .addActiveInstance('instance-1') + .addActiveInstance('instance-1', 'action group A') .advanceTime(10000) .addExecute() - .addActiveInstance('instance-1') + .addActiveInstance('instance-1', 'action group A') .getEvents(); const summary: AlertInstanceSummary = alertInstanceSummaryFromEventLog({ @@ -271,6 +275,79 @@ describe('alertInstanceSummaryFromEventLog', () => { Object { "instances": Object { "instance-1": Object { + "actionGroupId": "action group A", + "activeStartDate": "2020-06-18T00:00:00.000Z", + "muted": false, + "status": "Active", + }, + }, + "lastRun": "2020-06-18T00:00:10.000Z", + "status": "Active", + } + `); + }); + + test('alert with currently active instance with no action group in event log', async () => { + const alert = createAlert({}); + const eventsFactory = new EventsFactory(); + const events = eventsFactory + .addExecute() + .addNewInstance('instance-1') + .addActiveInstance('instance-1', undefined) + .advanceTime(10000) + .addExecute() + .addActiveInstance('instance-1', undefined) + .getEvents(); + + const summary: AlertInstanceSummary = alertInstanceSummaryFromEventLog({ + alert, + events, + dateStart, + dateEnd, + }); + + const { lastRun, status, instances } = summary; + expect({ lastRun, status, instances }).toMatchInlineSnapshot(` + Object { + "instances": Object { + "instance-1": Object { + "actionGroupId": undefined, + "activeStartDate": "2020-06-18T00:00:00.000Z", + "muted": false, + "status": "Active", + }, + }, + "lastRun": "2020-06-18T00:00:10.000Z", + "status": "Active", + } + `); + }); + + test('alert with currently active instance that switched action groups', async () => { + const alert = createAlert({}); + const eventsFactory = new EventsFactory(); + const events = eventsFactory + .addExecute() + .addNewInstance('instance-1') + .addActiveInstance('instance-1', 'action group A') + .advanceTime(10000) + .addExecute() + .addActiveInstance('instance-1', 'action group B') + .getEvents(); + + const summary: AlertInstanceSummary = alertInstanceSummaryFromEventLog({ + alert, + events, + dateStart, + dateEnd, + }); + + const { lastRun, status, instances } = summary; + expect({ lastRun, status, instances }).toMatchInlineSnapshot(` + Object { + "instances": Object { + "instance-1": Object { + "actionGroupId": "action group B", "activeStartDate": "2020-06-18T00:00:00.000Z", "muted": false, "status": "Active", @@ -287,10 +364,10 @@ describe('alertInstanceSummaryFromEventLog', () => { const eventsFactory = new EventsFactory(); const events = eventsFactory .addExecute() - .addActiveInstance('instance-1') + .addActiveInstance('instance-1', 'action group A') .advanceTime(10000) .addExecute() - .addActiveInstance('instance-1') + .addActiveInstance('instance-1', 'action group A') .getEvents(); const summary: AlertInstanceSummary = alertInstanceSummaryFromEventLog({ @@ -305,6 +382,7 @@ describe('alertInstanceSummaryFromEventLog', () => { Object { "instances": Object { "instance-1": Object { + "actionGroupId": "action group A", "activeStartDate": undefined, "muted": false, "status": "Active", @@ -322,12 +400,12 @@ describe('alertInstanceSummaryFromEventLog', () => { const events = eventsFactory .addExecute() .addNewInstance('instance-1') - .addActiveInstance('instance-1') + .addActiveInstance('instance-1', 'action group A') .addNewInstance('instance-2') - .addActiveInstance('instance-2') + .addActiveInstance('instance-2', 'action group B') .advanceTime(10000) .addExecute() - .addActiveInstance('instance-1') + .addActiveInstance('instance-1', 'action group A') .addResolvedInstance('instance-2') .getEvents(); @@ -343,11 +421,13 @@ describe('alertInstanceSummaryFromEventLog', () => { Object { "instances": Object { "instance-1": Object { + "actionGroupId": "action group A", "activeStartDate": "2020-06-18T00:00:00.000Z", "muted": true, "status": "Active", }, "instance-2": Object { + "actionGroupId": undefined, "activeStartDate": undefined, "muted": true, "status": "OK", @@ -365,19 +445,19 @@ describe('alertInstanceSummaryFromEventLog', () => { const events = eventsFactory .addExecute() .addNewInstance('instance-1') - .addActiveInstance('instance-1') + .addActiveInstance('instance-1', 'action group A') .addNewInstance('instance-2') - .addActiveInstance('instance-2') + .addActiveInstance('instance-2', 'action group B') .advanceTime(10000) .addExecute() - .addActiveInstance('instance-1') + .addActiveInstance('instance-1', 'action group A') .addResolvedInstance('instance-2') .advanceTime(10000) .addExecute() - .addActiveInstance('instance-1') + .addActiveInstance('instance-1', 'action group B') .advanceTime(10000) .addExecute() - .addActiveInstance('instance-1') + .addActiveInstance('instance-1', 'action group B') .getEvents(); const summary: AlertInstanceSummary = alertInstanceSummaryFromEventLog({ @@ -392,11 +472,13 @@ describe('alertInstanceSummaryFromEventLog', () => { Object { "instances": Object { "instance-1": Object { + "actionGroupId": "action group B", "activeStartDate": "2020-06-18T00:00:00.000Z", "muted": false, "status": "Active", }, "instance-2": Object { + "actionGroupId": undefined, "activeStartDate": undefined, "muted": false, "status": "OK", @@ -452,14 +534,17 @@ export class EventsFactory { return this; } - addActiveInstance(instanceId: string): EventsFactory { + addActiveInstance(instanceId: string, actionGroupId: string | undefined): EventsFactory { + const kibanaAlerting = actionGroupId + ? { instance_id: instanceId, action_group_id: actionGroupId } + : { instance_id: instanceId }; this.events.push({ '@timestamp': this.date, event: { provider: EVENT_LOG_PROVIDER, action: EVENT_LOG_ACTIONS.activeInstance, }, - kibana: { alerting: { instance_id: instanceId } }, + kibana: { alerting: kibanaAlerting }, }); return this; } diff --git a/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.ts b/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.ts index 9a5e870c8199a2..8fed97a74435dc 100644 --- a/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.ts +++ b/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.ts @@ -78,10 +78,12 @@ export function alertInstanceSummaryFromEventLog( // intentionally no break here case EVENT_LOG_ACTIONS.activeInstance: status.status = 'Active'; + status.actionGroupId = event?.kibana?.alerting?.action_group_id; break; case EVENT_LOG_ACTIONS.resolvedInstance: status.status = 'OK'; status.activeStartDate = undefined; + status.actionGroupId = undefined; } } @@ -118,6 +120,7 @@ function getAlertInstanceStatus( const status: AlertInstanceStatus = { status: 'OK', muted: false, + actionGroupId: undefined, activeStartDate: undefined, }; instances.set(instanceId, status); diff --git a/x-pack/plugins/alerts/server/lib/error_with_reason.test.ts b/x-pack/plugins/alerts/server/lib/error_with_reason.test.ts index f31f5844003086..eff935966345f9 100644 --- a/x-pack/plugins/alerts/server/lib/error_with_reason.test.ts +++ b/x-pack/plugins/alerts/server/lib/error_with_reason.test.ts @@ -5,20 +5,21 @@ */ import { ErrorWithReason, getReasonFromError, isErrorWithReason } from './error_with_reason'; +import { AlertExecutionStatusErrorReasons } from '../types'; describe('ErrorWithReason', () => { const plainError = new Error('well, actually'); - const errorWithReason = new ErrorWithReason('decrypt', plainError); + const errorWithReason = new ErrorWithReason(AlertExecutionStatusErrorReasons.Decrypt, plainError); test('ErrorWithReason class', () => { expect(errorWithReason.message).toBe(plainError.message); expect(errorWithReason.error).toBe(plainError); - expect(errorWithReason.reason).toBe('decrypt'); + expect(errorWithReason.reason).toBe(AlertExecutionStatusErrorReasons.Decrypt); }); test('getReasonFromError()', () => { expect(getReasonFromError(plainError)).toBe('unknown'); - expect(getReasonFromError(errorWithReason)).toBe('decrypt'); + expect(getReasonFromError(errorWithReason)).toBe(AlertExecutionStatusErrorReasons.Decrypt); }); test('isErrorWithReason()', () => { diff --git a/x-pack/plugins/alerts/server/lib/error_with_reason.ts b/x-pack/plugins/alerts/server/lib/error_with_reason.ts index 29eb666e644272..a732b44ef2238c 100644 --- a/x-pack/plugins/alerts/server/lib/error_with_reason.ts +++ b/x-pack/plugins/alerts/server/lib/error_with_reason.ts @@ -21,7 +21,7 @@ export function getReasonFromError(error: Error): AlertExecutionStatusErrorReaso if (isErrorWithReason(error)) { return error.reason; } - return 'unknown'; + return AlertExecutionStatusErrorReasons.Unknown; } export function isErrorWithReason(error: Error | ErrorWithReason): error is ErrorWithReason { diff --git a/x-pack/plugins/alerts/server/lib/is_alert_not_found_error.test.ts b/x-pack/plugins/alerts/server/lib/is_alert_not_found_error.test.ts index b570957d82de4a..ab21dc77fa251c 100644 --- a/x-pack/plugins/alerts/server/lib/is_alert_not_found_error.test.ts +++ b/x-pack/plugins/alerts/server/lib/is_alert_not_found_error.test.ts @@ -8,6 +8,7 @@ import { isAlertSavedObjectNotFoundError } from './is_alert_not_found_error'; import { ErrorWithReason } from './error_with_reason'; import { SavedObjectsErrorHelpers } from '../../../../../src/core/server'; import uuid from 'uuid'; +import { AlertExecutionStatusErrorReasons } from '../types'; describe('isAlertSavedObjectNotFoundError', () => { const id = uuid.v4(); @@ -25,7 +26,7 @@ describe('isAlertSavedObjectNotFoundError', () => { }); test('identifies SavedObjects Not Found errors wrapped in an ErrorWithReason', () => { - const error = new ErrorWithReason('read', errorSONF); + const error = new ErrorWithReason(AlertExecutionStatusErrorReasons.Read, errorSONF); expect(isAlertSavedObjectNotFoundError(error, id)).toBe(true); }); }); diff --git a/x-pack/plugins/alerts/server/mocks.ts b/x-pack/plugins/alerts/server/mocks.ts index 05d64bdbb77f4f..cfae4c650bd42c 100644 --- a/x-pack/plugins/alerts/server/mocks.ts +++ b/x-pack/plugins/alerts/server/mocks.ts @@ -25,6 +25,7 @@ const createStartMock = () => { const mock: jest.Mocked = { listTypes: jest.fn(), getAlertsClientWithRequest: jest.fn().mockResolvedValue(alertsClientMock.create()), + getFrameworkHealth: jest.fn(), }; return mock; }; diff --git a/x-pack/plugins/alerts/server/plugin.test.ts b/x-pack/plugins/alerts/server/plugin.test.ts index b13a1c62f66022..715fbc6aeed459 100644 --- a/x-pack/plugins/alerts/server/plugin.test.ts +++ b/x-pack/plugins/alerts/server/plugin.test.ts @@ -5,7 +5,7 @@ */ import { AlertingPlugin, AlertingPluginsSetup, AlertingPluginsStart } from './plugin'; -import { coreMock } from '../../../../src/core/server/mocks'; +import { coreMock, statusServiceMock } from '../../../../src/core/server/mocks'; import { licensingMock } from '../../licensing/server/mocks'; import { encryptedSavedObjectsMock } from '../../encrypted_saved_objects/server/mocks'; import { taskManagerMock } from '../../task_manager/server/mocks'; @@ -13,15 +13,21 @@ import { eventLogServiceMock } from '../../event_log/server/event_log_service.mo import { KibanaRequest, CoreSetup } from 'kibana/server'; import { featuresPluginMock } from '../../features/server/mocks'; import { KibanaFeature } from '../../features/server'; +import { AlertsConfig } from './config'; describe('Alerting Plugin', () => { describe('setup()', () => { it('should log warning when Encrypted Saved Objects plugin is using an ephemeral encryption key', async () => { - const context = coreMock.createPluginInitializerContext(); + const context = coreMock.createPluginInitializerContext({ + healthCheck: { + interval: '5m', + }, + }); const plugin = new AlertingPlugin(context); const coreSetup = coreMock.createSetup(); const encryptedSavedObjectsSetup = encryptedSavedObjectsMock.createSetup(); + const statusMock = statusServiceMock.createSetupContract(); await plugin.setup( ({ ...coreSetup, @@ -29,6 +35,7 @@ describe('Alerting Plugin', () => { ...coreSetup.http, route: jest.fn(), }, + status: statusMock, } as unknown) as CoreSetup, ({ licensing: licensingMock.createSetup(), @@ -38,6 +45,7 @@ describe('Alerting Plugin', () => { } as unknown) as AlertingPluginsSetup ); + expect(statusMock.set).toHaveBeenCalledTimes(1); expect(encryptedSavedObjectsSetup.usingEphemeralEncryptionKey).toEqual(true); expect(context.logger.get().warn).toHaveBeenCalledWith( 'APIs are disabled due to the Encrypted Saved Objects plugin using an ephemeral encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in kibana.yml.' @@ -55,7 +63,11 @@ describe('Alerting Plugin', () => { */ describe('getAlertsClientWithRequest()', () => { it('throws error when encryptedSavedObjects plugin has usingEphemeralEncryptionKey set to true', async () => { - const context = coreMock.createPluginInitializerContext(); + const context = coreMock.createPluginInitializerContext({ + healthCheck: { + interval: '5m', + }, + }); const plugin = new AlertingPlugin(context); const coreSetup = coreMock.createSetup(); @@ -98,7 +110,11 @@ describe('Alerting Plugin', () => { }); it(`doesn't throw error when encryptedSavedObjects plugin has usingEphemeralEncryptionKey set to false`, async () => { - const context = coreMock.createPluginInitializerContext(); + const context = coreMock.createPluginInitializerContext({ + healthCheck: { + interval: '5m', + }, + }); const plugin = new AlertingPlugin(context); const coreSetup = coreMock.createSetup(); diff --git a/x-pack/plugins/alerts/server/plugin.ts b/x-pack/plugins/alerts/server/plugin.ts index 75873a2845c15e..1fa89606a76fc7 100644 --- a/x-pack/plugins/alerts/server/plugin.ts +++ b/x-pack/plugins/alerts/server/plugin.ts @@ -6,6 +6,7 @@ import type { PublicMethodsOf } from '@kbn/utility-types'; import { first, map } from 'rxjs/operators'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; +import { combineLatest } from 'rxjs'; import { SecurityPluginSetup } from '../../security/server'; import { EncryptedSavedObjectsPluginSetup, @@ -30,6 +31,8 @@ import { SharedGlobalConfig, ElasticsearchServiceStart, ILegacyClusterClient, + StatusServiceSetup, + ServiceStatus, } from '../../../../src/core/server'; import { @@ -56,12 +59,19 @@ import { PluginSetupContract as ActionsPluginSetupContract, PluginStartContract as ActionsPluginStartContract, } from '../../actions/server'; -import { Services } from './types'; +import { AlertsHealth, Services } from './types'; import { registerAlertsUsageCollector } from './usage'; import { initializeAlertingTelemetry, scheduleAlertingTelemetry } from './usage/task'; import { IEventLogger, IEventLogService, IEventLogClientService } from '../../event_log/server'; import { PluginStartContract as FeaturesPluginStart } from '../../features/server'; import { setupSavedObjects } from './saved_objects'; +import { + getHealthStatusStream, + scheduleAlertingHealthCheck, + initializeAlertingHealth, +} from './health'; +import { AlertsConfig } from './config'; +import { getHealth } from './health/get_health'; export const EVENT_LOG_PROVIDER = 'alerting'; export const EVENT_LOG_ACTIONS = { @@ -78,6 +88,7 @@ export interface PluginSetupContract { export interface PluginStartContract { listTypes: AlertTypeRegistry['list']; getAlertsClientWithRequest(request: KibanaRequest): PublicMethodsOf; + getFrameworkHealth: () => Promise; } export interface AlertingPluginsSetup { @@ -89,6 +100,7 @@ export interface AlertingPluginsSetup { spaces?: SpacesPluginSetup; usageCollection?: UsageCollectionSetup; eventLog: IEventLogService; + statusService: StatusServiceSetup; } export interface AlertingPluginsStart { actions: ActionsPluginStartContract; @@ -99,6 +111,7 @@ export interface AlertingPluginsStart { } export class AlertingPlugin { + private readonly config: Promise; private readonly logger: Logger; private alertTypeRegistry?: AlertTypeRegistry; private readonly taskRunnerFactory: TaskRunnerFactory; @@ -115,6 +128,7 @@ export class AlertingPlugin { private eventLogger?: IEventLogger; constructor(initializerContext: PluginInitializerContext) { + this.config = initializerContext.config.create().pipe(first()).toPromise(); this.logger = initializerContext.logger.get('plugins', 'alerting'); this.taskRunnerFactory = new TaskRunnerFactory(); this.alertsClientFactory = new AlertsClientFactory(); @@ -186,6 +200,25 @@ export class AlertingPlugin { }); } + core.getStartServices().then(async ([, startPlugins]) => { + core.status.set( + combineLatest([ + core.status.derivedStatus$, + getHealthStatusStream(startPlugins.taskManager), + ]).pipe( + map(([derivedStatus, healthStatus]) => { + if (healthStatus.level > derivedStatus.level) { + return healthStatus as ServiceStatus; + } else { + return derivedStatus; + } + }) + ) + ); + }); + + initializeAlertingHealth(this.logger, plugins.taskManager, core.getStartServices()); + core.http.registerRouteHandlerContext('alerting', this.createRouteHandlerContext(core)); // Routes @@ -275,10 +308,13 @@ export class AlertingPlugin { }); scheduleAlertingTelemetry(this.telemetryLogger, plugins.taskManager); + scheduleAlertingHealthCheck(this.logger, this.config, plugins.taskManager); return { listTypes: alertTypeRegistry!.list.bind(this.alertTypeRegistry!), getAlertsClientWithRequest, + getFrameworkHealth: async () => + await getHealth(core.savedObjects.createInternalRepository(['alert'])), }; } @@ -293,6 +329,8 @@ export class AlertingPlugin { return alertsClientFactory!.create(request, savedObjects); }, listTypes: alertTypeRegistry!.list.bind(alertTypeRegistry!), + getFrameworkHealth: async () => + await getHealth(savedObjects.createInternalRepository(['alert'])), }; }; }; diff --git a/x-pack/plugins/alerts/server/routes/_mock_handler_arguments.ts b/x-pack/plugins/alerts/server/routes/_mock_handler_arguments.ts index 3d13fc65ab260e..b3f407b20c142c 100644 --- a/x-pack/plugins/alerts/server/routes/_mock_handler_arguments.ts +++ b/x-pack/plugins/alerts/server/routes/_mock_handler_arguments.ts @@ -14,7 +14,7 @@ import { identity } from 'lodash'; import type { MethodKeysOf } from '@kbn/utility-types'; import { httpServerMock } from '../../../../../src/core/server/mocks'; import { alertsClientMock, AlertsClientMock } from '../alerts_client.mock'; -import { AlertType } from '../../common'; +import { AlertsHealth, AlertType } from '../../common'; import { elasticsearchServiceMock } from '../../../../../src/core/server/mocks'; export function mockHandlerArguments( @@ -22,10 +22,13 @@ export function mockHandlerArguments( alertsClient = alertsClientMock.create(), listTypes: listTypesRes = [], esClient = elasticsearchServiceMock.createLegacyClusterClient(), + getFrameworkHealth, }: { alertsClient?: AlertsClientMock; listTypes?: AlertType[]; esClient?: jest.Mocked; + getFrameworkHealth?: jest.MockInstance, []> & + (() => Promise); }, req: unknown, res?: Array> @@ -39,6 +42,7 @@ export function mockHandlerArguments( getAlertsClient() { return alertsClient || alertsClientMock.create(); }, + getFrameworkHealth, }, } as unknown) as RequestHandlerContext, req as KibanaRequest, diff --git a/x-pack/plugins/alerts/server/routes/health.test.ts b/x-pack/plugins/alerts/server/routes/health.test.ts index ce782dbd631a5a..d1967c6dd9bf84 100644 --- a/x-pack/plugins/alerts/server/routes/health.test.ts +++ b/x-pack/plugins/alerts/server/routes/health.test.ts @@ -11,13 +11,34 @@ import { elasticsearchServiceMock } from '../../../../../src/core/server/mocks'; import { verifyApiAccess } from '../lib/license_api_access'; import { mockLicenseState } from '../lib/license_state.mock'; import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/server/mocks'; +import { alertsClientMock } from '../alerts_client.mock'; +import { HealthStatus } from '../types'; +import { alertsMock } from '../mocks'; +const alertsClient = alertsClientMock.create(); jest.mock('../lib/license_api_access.ts', () => ({ verifyApiAccess: jest.fn(), })); +const alerting = alertsMock.createStart(); + +const currentDate = new Date().toISOString(); beforeEach(() => { jest.resetAllMocks(); + alerting.getFrameworkHealth.mockResolvedValue({ + decryptionHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, + executionHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, + readHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, + }); }); describe('healthRoute', () => { @@ -46,7 +67,7 @@ describe('healthRoute', () => { const esClient = elasticsearchServiceMock.createLegacyClusterClient(); esClient.callAsInternalUser.mockReturnValue(Promise.resolve({})); - const [context, req, res] = mockHandlerArguments({ esClient }, {}, ['ok']); + const [context, req, res] = mockHandlerArguments({ esClient, alertsClient }, {}, ['ok']); await handler(context, req, res); @@ -75,16 +96,32 @@ describe('healthRoute', () => { const esClient = elasticsearchServiceMock.createLegacyClusterClient(); esClient.callAsInternalUser.mockReturnValue(Promise.resolve({})); - const [context, req, res] = mockHandlerArguments({ esClient }, {}, ['ok']); + const [context, req, res] = mockHandlerArguments( + { esClient, alertsClient, getFrameworkHealth: alerting.getFrameworkHealth }, + {}, + ['ok'] + ); - expect(await handler(context, req, res)).toMatchInlineSnapshot(` - Object { - "body": Object { - "hasPermanentEncryptionKey": false, - "isSufficientlySecure": true, + expect(await handler(context, req, res)).toStrictEqual({ + body: { + alertingFrameworkHeath: { + decryptionHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, + executionHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, + readHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, }, - } - `); + hasPermanentEncryptionKey: false, + isSufficientlySecure: true, + }, + }); }); it('evaluates missing security info from the usage api to mean that the security plugin is disbled', async () => { @@ -99,16 +136,32 @@ describe('healthRoute', () => { const esClient = elasticsearchServiceMock.createLegacyClusterClient(); esClient.callAsInternalUser.mockReturnValue(Promise.resolve({})); - const [context, req, res] = mockHandlerArguments({ esClient }, {}, ['ok']); + const [context, req, res] = mockHandlerArguments( + { esClient, alertsClient, getFrameworkHealth: alerting.getFrameworkHealth }, + {}, + ['ok'] + ); - expect(await handler(context, req, res)).toMatchInlineSnapshot(` - Object { - "body": Object { - "hasPermanentEncryptionKey": true, - "isSufficientlySecure": true, + expect(await handler(context, req, res)).toStrictEqual({ + body: { + alertingFrameworkHeath: { + decryptionHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, + executionHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, + readHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, }, - } - `); + hasPermanentEncryptionKey: true, + isSufficientlySecure: true, + }, + }); }); it('evaluates missing security http info from the usage api to mean that the security plugin is disbled', async () => { @@ -123,16 +176,32 @@ describe('healthRoute', () => { const esClient = elasticsearchServiceMock.createLegacyClusterClient(); esClient.callAsInternalUser.mockReturnValue(Promise.resolve({ security: {} })); - const [context, req, res] = mockHandlerArguments({ esClient }, {}, ['ok']); + const [context, req, res] = mockHandlerArguments( + { esClient, alertsClient, getFrameworkHealth: alerting.getFrameworkHealth }, + {}, + ['ok'] + ); - expect(await handler(context, req, res)).toMatchInlineSnapshot(` - Object { - "body": Object { - "hasPermanentEncryptionKey": true, - "isSufficientlySecure": true, + expect(await handler(context, req, res)).toStrictEqual({ + body: { + alertingFrameworkHeath: { + decryptionHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, + executionHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, + readHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, }, - } - `); + hasPermanentEncryptionKey: true, + isSufficientlySecure: true, + }, + }); }); it('evaluates security enabled, and missing ssl info from the usage api to mean that the user cannot generate keys', async () => { @@ -147,16 +216,32 @@ describe('healthRoute', () => { const esClient = elasticsearchServiceMock.createLegacyClusterClient(); esClient.callAsInternalUser.mockReturnValue(Promise.resolve({ security: { enabled: true } })); - const [context, req, res] = mockHandlerArguments({ esClient }, {}, ['ok']); + const [context, req, res] = mockHandlerArguments( + { esClient, alertsClient, getFrameworkHealth: alerting.getFrameworkHealth }, + {}, + ['ok'] + ); - expect(await handler(context, req, res)).toMatchInlineSnapshot(` - Object { - "body": Object { - "hasPermanentEncryptionKey": true, - "isSufficientlySecure": false, + expect(await handler(context, req, res)).toStrictEqual({ + body: { + alertingFrameworkHeath: { + decryptionHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, + executionHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, + readHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, }, - } - `); + hasPermanentEncryptionKey: true, + isSufficientlySecure: false, + }, + }); }); it('evaluates security enabled, SSL info present but missing http info from the usage api to mean that the user cannot generate keys', async () => { @@ -173,16 +258,32 @@ describe('healthRoute', () => { Promise.resolve({ security: { enabled: true, ssl: {} } }) ); - const [context, req, res] = mockHandlerArguments({ esClient }, {}, ['ok']); + const [context, req, res] = mockHandlerArguments( + { esClient, alertsClient, getFrameworkHealth: alerting.getFrameworkHealth }, + {}, + ['ok'] + ); - expect(await handler(context, req, res)).toMatchInlineSnapshot(` - Object { - "body": Object { - "hasPermanentEncryptionKey": true, - "isSufficientlySecure": false, + expect(await handler(context, req, res)).toStrictEqual({ + body: { + alertingFrameworkHeath: { + decryptionHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, + executionHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, + readHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, }, - } - `); + hasPermanentEncryptionKey: true, + isSufficientlySecure: false, + }, + }); }); it('evaluates security and tls enabled to mean that the user can generate keys', async () => { @@ -199,15 +300,31 @@ describe('healthRoute', () => { Promise.resolve({ security: { enabled: true, ssl: { http: { enabled: true } } } }) ); - const [context, req, res] = mockHandlerArguments({ esClient }, {}, ['ok']); + const [context, req, res] = mockHandlerArguments( + { esClient, alertsClient, getFrameworkHealth: alerting.getFrameworkHealth }, + {}, + ['ok'] + ); - expect(await handler(context, req, res)).toMatchInlineSnapshot(` - Object { - "body": Object { - "hasPermanentEncryptionKey": true, - "isSufficientlySecure": true, + expect(await handler(context, req, res)).toStrictEqual({ + body: { + alertingFrameworkHeath: { + decryptionHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, + executionHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, + readHealth: { + status: HealthStatus.OK, + timestamp: currentDate, + }, }, - } - `); + hasPermanentEncryptionKey: true, + isSufficientlySecure: true, + }, + }); }); }); diff --git a/x-pack/plugins/alerts/server/routes/health.ts b/x-pack/plugins/alerts/server/routes/health.ts index b66e28b24e8a74..bfd5b1e2722878 100644 --- a/x-pack/plugins/alerts/server/routes/health.ts +++ b/x-pack/plugins/alerts/server/routes/health.ts @@ -43,6 +43,9 @@ export function healthRoute( res: KibanaResponseFactory ): Promise { verifyApiAccess(licenseState); + if (!context.alerting) { + return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); + } try { const { security: { @@ -57,9 +60,12 @@ export function healthRoute( path: '/_xpack/usage', }); + const alertingFrameworkHeath = await context.alerting.getFrameworkHealth(); + const frameworkHealth: AlertingFrameworkHealth = { isSufficientlySecure: !isSecurityEnabled || (isSecurityEnabled && isTLSEnabled), hasPermanentEncryptionKey: !encryptedSavedObjects.usingEphemeralEncryptionKey, + alertingFrameworkHeath, }; return res.ok({ diff --git a/x-pack/plugins/alerts/server/task_runner/task_runner.test.ts b/x-pack/plugins/alerts/server/task_runner/task_runner.test.ts index 86e78dea66a095..4d0d69010914e2 100644 --- a/x-pack/plugins/alerts/server/task_runner/task_runner.test.ts +++ b/x-pack/plugins/alerts/server/task_runner/task_runner.test.ts @@ -292,6 +292,7 @@ describe('Task Runner', () => { kibana: { alerting: { instance_id: '1', + action_group_id: 'default', }, saved_objects: [ { @@ -302,7 +303,7 @@ describe('Task Runner', () => { }, ], }, - message: "test:1: 'alert-name' active instance: '1'", + message: "test:1: 'alert-name' active instance: '1' in actionGroup: 'default'", }); expect(eventLogger.logEvent).toHaveBeenCalledWith({ event: { @@ -424,6 +425,7 @@ describe('Task Runner', () => { }, "kibana": Object { "alerting": Object { + "action_group_id": undefined, "instance_id": "1", }, "saved_objects": Array [ @@ -445,6 +447,7 @@ describe('Task Runner', () => { }, "kibana": Object { "alerting": Object { + "action_group_id": "default", "instance_id": "1", }, "saved_objects": Array [ @@ -456,7 +459,7 @@ describe('Task Runner', () => { }, ], }, - "message": "test:1: 'alert-name' active instance: '1'", + "message": "test:1: 'alert-name' active instance: '1' in actionGroup: 'default'", }, ], Array [ @@ -565,6 +568,7 @@ describe('Task Runner', () => { }, "kibana": Object { "alerting": Object { + "action_group_id": undefined, "instance_id": "2", }, "saved_objects": Array [ @@ -586,6 +590,7 @@ describe('Task Runner', () => { }, "kibana": Object { "alerting": Object { + "action_group_id": "default", "instance_id": "1", }, "saved_objects": Array [ @@ -597,7 +602,7 @@ describe('Task Runner', () => { }, ], }, - "message": "test:1: 'alert-name' active instance: '1'", + "message": "test:1: 'alert-name' active instance: '1' in actionGroup: 'default'", }, ], ] diff --git a/x-pack/plugins/alerts/server/task_runner/task_runner.ts b/x-pack/plugins/alerts/server/task_runner/task_runner.ts index 2611ba766173ba..86bf7006e8d09e 100644 --- a/x-pack/plugins/alerts/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerts/server/task_runner/task_runner.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import type { PublicMethodsOf } from '@kbn/utility-types'; -import { pickBy, mapValues, without } from 'lodash'; +import { Dictionary, pickBy, mapValues, without } from 'lodash'; import { Logger, KibanaRequest } from '../../../../../src/core/server'; import { TaskRunnerContext } from './task_runner_factory'; import { ConcreteTaskInstance, throwUnrecoverableError } from '../../../task_manager/server'; @@ -28,6 +28,7 @@ import { AlertExecutorOptions, SanitizedAlert, AlertExecutionStatus, + AlertExecutionStatusErrorReasons, } from '../types'; import { promiseResult, map, Resultable, asOk, asErr, resolveErr } from '../lib/result_type'; import { taskInstanceToAlertTaskInstance } from './alert_task_instance'; @@ -211,7 +212,7 @@ export class TaskRunner { event.event = event.event || {}; event.event.outcome = 'failure'; eventLogger.logEvent(event); - throw new ErrorWithReason('execute', err); + throw new ErrorWithReason(AlertExecutionStatusErrorReasons.Execute, err); } eventLogger.stopTiming(event); @@ -224,11 +225,10 @@ export class TaskRunner { const instancesWithScheduledActions = pickBy(alertInstances, (alertInstance: AlertInstance) => alertInstance.hasScheduledActions() ); - const currentAlertInstanceIds = Object.keys(instancesWithScheduledActions); generateNewAndResolvedInstanceEvents({ eventLogger, originalAlertInstanceIds, - currentAlertInstanceIds, + currentAlertInstances: instancesWithScheduledActions, alertId, alertLabel, namespace, @@ -289,7 +289,7 @@ export class TaskRunner { try { apiKey = await this.getApiKeyForAlertPermissions(alertId, spaceId); } catch (err) { - throw new ErrorWithReason('decrypt', err); + throw new ErrorWithReason(AlertExecutionStatusErrorReasons.Decrypt, err); } const [services, alertsClient] = this.getServicesWithSpaceLevelPermissions(spaceId, apiKey); @@ -299,7 +299,7 @@ export class TaskRunner { try { alert = await alertsClient.get({ id: alertId }); } catch (err) { - throw new ErrorWithReason('read', err); + throw new ErrorWithReason(AlertExecutionStatusErrorReasons.Read, err); } return { @@ -382,7 +382,7 @@ export class TaskRunner { interface GenerateNewAndResolvedInstanceEventsParams { eventLogger: IEventLogger; originalAlertInstanceIds: string[]; - currentAlertInstanceIds: string[]; + currentAlertInstances: Dictionary; alertId: string; alertLabel: string; namespace: string | undefined; @@ -393,9 +393,10 @@ function generateNewAndResolvedInstanceEvents(params: GenerateNewAndResolvedInst eventLogger, alertId, namespace, - currentAlertInstanceIds, + currentAlertInstances, originalAlertInstanceIds, } = params; + const currentAlertInstanceIds = Object.keys(currentAlertInstances); const newIds = without(currentAlertInstanceIds, ...originalAlertInstanceIds); const resolvedIds = without(originalAlertInstanceIds, ...currentAlertInstanceIds); @@ -411,11 +412,12 @@ function generateNewAndResolvedInstanceEvents(params: GenerateNewAndResolvedInst } for (const id of currentAlertInstanceIds) { - const message = `${params.alertLabel} active instance: '${id}'`; - logInstanceEvent(id, EVENT_LOG_ACTIONS.activeInstance, message); + const actionGroup = currentAlertInstances[id].getScheduledActionOptions()?.actionGroup; + const message = `${params.alertLabel} active instance: '${id}' in actionGroup: '${actionGroup}'`; + logInstanceEvent(id, EVENT_LOG_ACTIONS.activeInstance, message, actionGroup); } - function logInstanceEvent(instanceId: string, action: string, message: string) { + function logInstanceEvent(instanceId: string, action: string, message: string, group?: string) { const event: IEvent = { event: { action, @@ -423,6 +425,7 @@ function generateNewAndResolvedInstanceEvents(params: GenerateNewAndResolvedInst kibana: { alerting: { instance_id: instanceId, + action_group_id: group, }, saved_objects: [ { diff --git a/x-pack/plugins/alerts/server/types.ts b/x-pack/plugins/alerts/server/types.ts index 42eef9bba10e52..9226461f6e30a4 100644 --- a/x-pack/plugins/alerts/server/types.ts +++ b/x-pack/plugins/alerts/server/types.ts @@ -27,6 +27,7 @@ import { AlertInstanceState, AlertExecutionStatuses, AlertExecutionStatusErrorReasons, + AlertsHealth, } from '../common'; export type WithoutQueryAndParams = Pick>; @@ -39,6 +40,7 @@ declare module 'src/core/server' { alerting?: { getAlertsClient: () => AlertsClient; listTypes: AlertTypeRegistry['list']; + getFrameworkHealth: () => Promise; }; } } @@ -172,4 +174,10 @@ export interface AlertingPlugin { start: PluginStartContract; } +export interface AlertsConfigType { + healthCheck: { + interval: string; + }; +} + export type AlertTypeRegistry = PublicMethodsOf; diff --git a/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js b/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js index 72b49bb85b7a59..0ecda7a113de75 100644 --- a/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js +++ b/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js @@ -1,3 +1,3 @@ module.exports = { - __version: '5.5.0', -}; + "__version": "5.4.0" +} diff --git a/x-pack/plugins/apm/e2e/package.json b/x-pack/plugins/apm/e2e/package.json deleted file mode 100644 index 5839f4d58537c0..00000000000000 --- a/x-pack/plugins/apm/e2e/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "apm-cypress", - "version": "1.0.0", - "main": "index.js", - "license": "MIT", - "scripts": { - "cypress:open": "../../../../node_modules/.bin/cypress open", - "cypress:run": "../../../../node_modules/.bin/cypress run --spec **/*.feature" - } -} \ No newline at end of file diff --git a/x-pack/plugins/apm/e2e/run-e2e.sh b/x-pack/plugins/apm/e2e/run-e2e.sh index 6cdae93aec63be..85ab67bbf9a10d 100755 --- a/x-pack/plugins/apm/e2e/run-e2e.sh +++ b/x-pack/plugins/apm/e2e/run-e2e.sh @@ -20,6 +20,8 @@ normal=$(tput sgr0) E2E_DIR="${0%/*}" TMP_DIR="tmp" APM_IT_DIR="tmp/apm-integration-testing" +WAIT_ON_BIN="../../../../node_modules/.bin/wait-on" +CYPRESS_BIN="../../../../node_modules/.bin/cypress" cd ${E2E_DIR} @@ -92,14 +94,6 @@ if [ $? -ne 0 ]; then exit 1 fi -# -# Cypress -################################################## -echo "" # newline -echo "${bold}Cypress (logs: ${E2E_DIR}${TMP_DIR}/e2e-yarn.log)${normal}" -echo "Installing cypress dependencies " -yarn &> ${TMP_DIR}/e2e-yarn.log - # # Static mock data ################################################## @@ -148,7 +142,7 @@ fi echo "" # newline echo "${bold}Waiting for Kibana to start...${normal}" echo "Note: you need to start Kibana manually. Find the instructions at the top." -yarn wait-on -i 500 -w 500 http-get://admin:changeme@localhost:$KIBANA_PORT/api/status > /dev/null +$WAIT_ON_BIN -i 500 -w 500 http-get://admin:changeme@localhost:$KIBANA_PORT/api/status > /dev/null ## Workaround to wait for the http server running ## See: https://github.com/elastic/kibana/issues/66326 @@ -165,7 +159,7 @@ echo "✅ Setup completed successfully. Running tests..." # # run cypress tests ################################################## -yarn cypress run --config pageLoadTimeout=100000,watchForFileChanges=true +$CYPRESS_BIN run --config pageLoadTimeout=100000,watchForFileChanges=true e2e_status=$? # @@ -173,7 +167,7 @@ e2e_status=$? ################################################## echo "${bold}If you want to run the test interactively, run:${normal}" echo "" # newline -echo "cd ${E2E_DIR} && yarn cypress open --config pageLoadTimeout=100000,watchForFileChanges=true" +echo "cd ${E2E_DIR} && ${CYPRESS_BIN} open --config pageLoadTimeout=100000,watchForFileChanges=true" # Report the e2e status at the very end if [ $e2e_status -ne 0 ]; then diff --git a/x-pack/plugins/apm/public/components/alerting/register_apm_alerts.ts b/x-pack/plugins/apm/public/components/alerting/register_apm_alerts.ts index 0eeb31927b2f59..988e335af5b7cc 100644 --- a/x-pack/plugins/apm/public/components/alerting/register_apm_alerts.ts +++ b/x-pack/plugins/apm/public/components/alerting/register_apm_alerts.ts @@ -22,6 +22,9 @@ export function registerApmAlerts( 'Alert when the number of errors in a service exceeds a defined threshold.', }), iconClass: 'bell', + documentationUrl(docLinks) { + return `${docLinks.ELASTIC_WEBSITE_URL}guide/en/kibana/${docLinks.DOC_LINK_VERSION}/apm-alerts.html`; + }, alertParamsExpression: lazy(() => import('./ErrorCountAlertTrigger')), validate: () => ({ errors: [], @@ -53,6 +56,9 @@ export function registerApmAlerts( } ), iconClass: 'bell', + documentationUrl(docLinks) { + return `${docLinks.ELASTIC_WEBSITE_URL}guide/en/kibana/${docLinks.DOC_LINK_VERSION}/apm-alerts.html`; + }, alertParamsExpression: lazy( () => import('./TransactionDurationAlertTrigger') ), @@ -87,6 +93,9 @@ export function registerApmAlerts( } ), iconClass: 'bell', + documentationUrl(docLinks) { + return `${docLinks.ELASTIC_WEBSITE_URL}guide/en/kibana/${docLinks.DOC_LINK_VERSION}/apm-alerts.html`; + }, alertParamsExpression: lazy( () => import('./TransactionErrorRateAlertTrigger') ), @@ -121,6 +130,9 @@ export function registerApmAlerts( } ), iconClass: 'bell', + documentationUrl(docLinks) { + return `${docLinks.ELASTIC_WEBSITE_URL}guide/en/kibana/${docLinks.DOC_LINK_VERSION}/apm-alerts.html`; + }, alertParamsExpression: lazy( () => import('./TransactionDurationAnomalyAlertTrigger') ), diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/__test__/__snapshots__/List.test.tsx.snap b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/__test__/__snapshots__/List.test.tsx.snap index b5a558621e9ca9..1f34a0cef1ccf5 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/__test__/__snapshots__/List.test.tsx.snap +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/__test__/__snapshots__/List.test.tsx.snap @@ -826,7 +826,7 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = ` query={ Object { "end": "2018-01-10T10:06:41.050Z", - "kuery": "error.exception.type:AssertionError", + "kuery": "error.exception.type:\\"AssertionError\\"", "page": 0, "serviceName": "opbeans-python", "start": "2018-01-10T09:51:41.050Z", @@ -838,12 +838,12 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = ` > @@ -1065,7 +1065,7 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = ` query={ Object { "end": "2018-01-10T10:06:41.050Z", - "kuery": "error.exception.type:AssertionError", + "kuery": "error.exception.type:\\"AssertionError\\"", "page": 0, "serviceName": "opbeans-python", "start": "2018-01-10T09:51:41.050Z", @@ -1077,12 +1077,12 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = ` > @@ -1304,7 +1304,7 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = ` query={ Object { "end": "2018-01-10T10:06:41.050Z", - "kuery": "error.exception.type:AssertionError", + "kuery": "error.exception.type:\\"AssertionError\\"", "page": 0, "serviceName": "opbeans-python", "start": "2018-01-10T09:51:41.050Z", @@ -1316,12 +1316,12 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = ` > @@ -1543,7 +1543,7 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = ` query={ Object { "end": "2018-01-10T10:06:41.050Z", - "kuery": "error.exception.type:AssertionError", + "kuery": "error.exception.type:\\"AssertionError\\"", "page": 0, "serviceName": "opbeans-python", "start": "2018-01-10T09:51:41.050Z", @@ -1555,12 +1555,12 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = ` > diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/index.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/index.tsx index 33105189f9c3e4..e1f6239112555e 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/index.tsx @@ -107,7 +107,7 @@ function ErrorGroupList({ items, serviceName }: Props) { query={ { ...urlParams, - kuery: `error.exception.type:${type}`, + kuery: `error.exception.type:"${type}"`, } as APMQueryParams } > diff --git a/x-pack/plugins/apm/server/index.ts b/x-pack/plugins/apm/server/index.ts index 090110b0454c03..29a0d1fdf42494 100644 --- a/x-pack/plugins/apm/server/index.ts +++ b/x-pack/plugins/apm/server/index.ts @@ -43,6 +43,7 @@ export const config = { ), telemetryCollectionEnabled: schema.boolean({ defaultValue: true }), metricsInterval: schema.number({ defaultValue: 30 }), + maxServiceEnvironments: schema.number({ defaultValue: 100 }), }), }; @@ -74,6 +75,7 @@ export function mergeConfigs( 'xpack.apm.serviceMapMaxTracesPerRequest': apmConfig.serviceMapMaxTracesPerRequest, 'xpack.apm.ui.enabled': apmConfig.ui.enabled, + 'xpack.apm.maxServiceEnvironments': apmConfig.maxServiceEnvironments, 'xpack.apm.ui.maxTraceItems': apmConfig.ui.maxTraceItems, 'xpack.apm.ui.transactionGroupBucketSize': apmConfig.ui.transactionGroupBucketSize, 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 7b63f2c354916c..ecda5b0e8504bf 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 @@ -66,6 +66,7 @@ export function registerErrorCountAlertType({ config, savedObjectsClient: services.savedObjectsClient, }); + const maxServiceEnvironments = config['xpack.apm.maxServiceEnvironments']; const searchParams = { index: indices['apm_oss.errorIndices'], @@ -100,6 +101,7 @@ export function registerErrorCountAlertType({ environments: { terms: { field: SERVICE_ENVIRONMENT, + size: maxServiceEnvironments, }, }, }, diff --git a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts index 1d8b664751ba29..d9e69c8f3b7d7c 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts @@ -75,6 +75,7 @@ export function registerTransactionDurationAlertType({ config, savedObjectsClient: services.savedObjectsClient, }); + const maxServiceEnvironments = config['xpack.apm.maxServiceEnvironments']; const searchParams = { index: indices['apm_oss.transactionIndices'], @@ -112,6 +113,7 @@ export function registerTransactionDurationAlertType({ environments: { terms: { field: SERVICE_ENVIRONMENT, + size: maxServiceEnvironments, }, }, }, 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 969f4ceaca93a9..06b296db5a4853 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 @@ -71,6 +71,7 @@ export function registerTransactionErrorRateAlertType({ config, savedObjectsClient: services.savedObjectsClient, }); + const maxServiceEnvironments = config['xpack.apm.maxServiceEnvironments']; const searchParams = { index: indices['apm_oss.transactionIndices'], @@ -120,6 +121,7 @@ export function registerTransactionErrorRateAlertType({ environments: { terms: { field: SERVICE_ENVIRONMENT, + size: maxServiceEnvironments, }, }, }, 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 95ff357937d471..39b4f7a7fe81b5 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 @@ -24,7 +24,8 @@ export async function getAllEnvironments({ searchAggregatedTransactions: boolean; includeMissing?: boolean; }) { - const { apmEventClient } = setup; + const { apmEventClient, config } = setup; + const maxServiceEnvironments = config['xpack.apm.maxServiceEnvironments']; // omit filter for service.name if "All" option is selected const serviceNameFilter = serviceName @@ -55,7 +56,7 @@ export async function getAllEnvironments({ environments: { terms: { field: SERVICE_ENVIRONMENT, - size: 100, + size: maxServiceEnvironments, ...(!serviceName ? { min_doc_count: 0 } : {}), missing: includeMissing ? ENVIRONMENT_NOT_DEFINED.value : undefined, }, 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 3a38f80c87b35e..a6818f96c728ee 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 @@ -366,6 +366,7 @@ Array [ "environments": Object { "terms": Object { "field": "service.environment", + "size": 100, }, }, }, diff --git a/x-pack/plugins/apm/server/lib/services/get_services/get_services_items_stats.ts b/x-pack/plugins/apm/server/lib/services/get_services/get_services_items_stats.ts index 7d190c5b664501..fac80cf22c310e 100644 --- a/x-pack/plugins/apm/server/lib/services/get_services/get_services_items_stats.ts +++ b/x-pack/plugins/apm/server/lib/services/get_services/get_services_items_stats.ts @@ -337,7 +337,8 @@ export const getEnvironments = async ({ setup, projection, }: AggregationParams) => { - const { apmEventClient } = setup; + const { apmEventClient, config } = setup; + const maxServiceEnvironments = config['xpack.apm.maxServiceEnvironments']; const response = await apmEventClient.search( mergeProjection(projection, { body: { @@ -352,6 +353,7 @@ export const getEnvironments = async ({ environments: { terms: { field: SERVICE_ENVIRONMENT, + size: maxServiceEnvironments, }, }, }, diff --git a/x-pack/plugins/apm/server/lib/settings/agent_configuration/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/settings/agent_configuration/__snapshots__/queries.test.ts.snap index 8db97a4929eb05..18ef3f44331d98 100644 --- a/x-pack/plugins/apm/server/lib/settings/agent_configuration/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/settings/agent_configuration/__snapshots__/queries.test.ts.snap @@ -127,7 +127,7 @@ Object { "terms": Object { "field": "service.environment", "missing": "ALL_OPTION_VALUE", - "size": 50, + "size": 100, }, }, }, diff --git a/x-pack/plugins/apm/server/lib/settings/agent_configuration/get_environments/get_existing_environments_for_service.ts b/x-pack/plugins/apm/server/lib/settings/agent_configuration/get_environments/get_existing_environments_for_service.ts index 8327ac59a95b2f..5e19f8f211cf70 100644 --- a/x-pack/plugins/apm/server/lib/settings/agent_configuration/get_environments/get_existing_environments_for_service.ts +++ b/x-pack/plugins/apm/server/lib/settings/agent_configuration/get_environments/get_existing_environments_for_service.ts @@ -18,7 +18,8 @@ export async function getExistingEnvironmentsForService({ serviceName: string | undefined; setup: Setup; }) { - const { internalClient, indices } = setup; + const { internalClient, indices, config } = setup; + const maxServiceEnvironments = config['xpack.apm.maxServiceEnvironments']; const bool = serviceName ? { filter: [{ term: { [SERVICE_NAME]: serviceName } }] } @@ -34,7 +35,7 @@ export async function getExistingEnvironmentsForService({ terms: { field: SERVICE_ENVIRONMENT, missing: ALL_OPTION_VALUE, - size: 50, + size: maxServiceEnvironments, }, }, }, diff --git a/x-pack/plugins/apm/server/lib/ui_filters/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/ui_filters/__snapshots__/queries.test.ts.snap index d94b766aee6a89..3baaefe203ce75 100644 --- a/x-pack/plugins/apm/server/lib/ui_filters/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/ui_filters/__snapshots__/queries.test.ts.snap @@ -15,6 +15,7 @@ Object { "terms": Object { "field": "service.environment", "missing": "ENVIRONMENT_NOT_DEFINED", + "size": 100, }, }, }, @@ -58,6 +59,7 @@ Object { "terms": Object { "field": "service.environment", "missing": "ENVIRONMENT_NOT_DEFINED", + "size": 100, }, }, }, diff --git a/x-pack/plugins/apm/server/lib/ui_filters/get_environments.ts b/x-pack/plugins/apm/server/lib/ui_filters/get_environments.ts index e72cc7e2483ad4..b9f25e20f9f730 100644 --- a/x-pack/plugins/apm/server/lib/ui_filters/get_environments.ts +++ b/x-pack/plugins/apm/server/lib/ui_filters/get_environments.ts @@ -24,7 +24,7 @@ export async function getEnvironments({ serviceName?: string; searchAggregatedTransactions: boolean; }) { - const { start, end, apmEventClient } = setup; + const { start, end, apmEventClient, config } = setup; const filter: ESFilter[] = [{ range: rangeFilter(start, end) }]; @@ -34,6 +34,8 @@ export async function getEnvironments({ }); } + const maxServiceEnvironments = config['xpack.apm.maxServiceEnvironments']; + const params = { apm: { events: [ @@ -56,6 +58,7 @@ export async function getEnvironments({ terms: { field: SERVICE_ENVIRONMENT, missing: ENVIRONMENT_NOT_DEFINED.value, + size: maxServiceEnvironments, }, }, }, diff --git a/x-pack/plugins/apm/server/utils/test_helpers.tsx b/x-pack/plugins/apm/server/utils/test_helpers.tsx index 18b990b35b5a58..21b59dc516d060 100644 --- a/x-pack/plugins/apm/server/utils/test_helpers.tsx +++ b/x-pack/plugins/apm/server/utils/test_helpers.tsx @@ -76,6 +76,9 @@ export async function inspectSearchParams( case 'xpack.apm.metricsInterval': return 30; + + case 'xpack.apm.maxServiceEnvironments': + return 100; } }, } diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/dropdown_filter/component/__stories__/__snapshots__/dropdown_filter.stories.storyshot b/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/dropdown_filter/component/__stories__/__snapshots__/dropdown_filter.stories.storyshot index 5ad49a207ed3ec..286c55994f27ec 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/dropdown_filter/component/__stories__/__snapshots__/dropdown_filter.stories.storyshot +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/dropdown_filter/component/__stories__/__snapshots__/dropdown_filter.stories.storyshot @@ -6,6 +6,7 @@ exports[`Storyshots renderers/DropdownFilter default 1`] = ` >