diff --git a/.eslintignore b/.eslintignore
index 2ed9ecf971ff3..4913192e81c1d 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -30,6 +30,7 @@ target
/x-pack/legacy/plugins/canvas/canvas_plugin_src/lib/flot-charts
/x-pack/legacy/plugins/canvas/shareable_runtime/build
/x-pack/legacy/plugins/canvas/storybook
+/x-pack/plugins/monitoring/public/lib/jquery_flot
/x-pack/legacy/plugins/infra/common/graphql/types.ts
/x-pack/legacy/plugins/infra/public/graphql/types.ts
/x-pack/legacy/plugins/infra/server/graphql/types.ts
diff --git a/.eslintrc.js b/.eslintrc.js
index c9b41ec711b7f..8b33ec83347a8 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -963,6 +963,12 @@ module.exports = {
jquery: true,
},
},
+ {
+ files: ['x-pack/plugins/monitoring/public/lib/jquery_flot/**/*.js'],
+ env: {
+ jquery: true,
+ },
+ },
/**
* TSVB overrides
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index c17538849660e..3981a8e1e9afe 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -84,6 +84,7 @@
/x-pack/legacy/plugins/ingest_manager/ @elastic/ingest-management
/x-pack/plugins/observability/ @elastic/logs-metrics-ui @elastic/apm-ui @elastic/uptime @elastic/ingest-management
/x-pack/legacy/plugins/monitoring/ @elastic/stack-monitoring-ui
+/x-pack/plugins/monitoring/ @elastic/stack-monitoring-ui
/x-pack/plugins/uptime @elastic/uptime
# Machine Learning
diff --git a/docs/development/core/public/kibana-plugin-core-public.appbase.defaultpath.md b/docs/development/core/public/kibana-plugin-core-public.appbase.defaultpath.md
new file mode 100644
index 0000000000000..51492756ef232
--- /dev/null
+++ b/docs/development/core/public/kibana-plugin-core-public.appbase.defaultpath.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [AppBase](./kibana-plugin-core-public.appbase.md) > [defaultPath](./kibana-plugin-core-public.appbase.defaultpath.md)
+
+## AppBase.defaultPath property
+
+Allow to define the default path a user should be directed to when navigating to the app. When defined, this value will be used as a default for the `path` option when calling [navigateToApp](./kibana-plugin-core-public.applicationstart.navigatetoapp.md)\`, and will also be appended to the [application navLink](./kibana-plugin-core-public.chromenavlink.md) in the navigation bar.
+
+Signature:
+
+```typescript
+defaultPath?: string;
+```
diff --git a/docs/development/core/public/kibana-plugin-core-public.appbase.md b/docs/development/core/public/kibana-plugin-core-public.appbase.md
index b73785647f23c..7b624f12ac1df 100644
--- a/docs/development/core/public/kibana-plugin-core-public.appbase.md
+++ b/docs/development/core/public/kibana-plugin-core-public.appbase.md
@@ -18,6 +18,7 @@ export interface AppBase
| [capabilities](./kibana-plugin-core-public.appbase.capabilities.md) | Partial<Capabilities> | Custom capabilities defined by the app. |
| [category](./kibana-plugin-core-public.appbase.category.md) | AppCategory | The category definition of the product See [AppCategory](./kibana-plugin-core-public.appcategory.md) See DEFAULT\_APP\_CATEGORIES for more reference |
| [chromeless](./kibana-plugin-core-public.appbase.chromeless.md) | boolean | Hide the UI chrome when the application is mounted. Defaults to false. Takes precedence over chrome service visibility settings. |
+| [defaultPath](./kibana-plugin-core-public.appbase.defaultpath.md) | string | Allow to define the default path a user should be directed to when navigating to the app. When defined, this value will be used as a default for the path option when calling [navigateToApp](./kibana-plugin-core-public.applicationstart.navigatetoapp.md)\`, and will also be appended to the [application navLink](./kibana-plugin-core-public.chromenavlink.md) in the navigation bar. |
| [euiIconType](./kibana-plugin-core-public.appbase.euiicontype.md) | string | A EUI iconType that will be used for the app's icon. This icon takes precendence over the icon property. |
| [icon](./kibana-plugin-core-public.appbase.icon.md) | string | A URL to an image file used as an icon. Used as a fallback if euiIconType is not provided. |
| [id](./kibana-plugin-core-public.appbase.id.md) | string | The unique identifier of the application |
diff --git a/docs/development/core/public/kibana-plugin-core-public.appupdatablefields.md b/docs/development/core/public/kibana-plugin-core-public.appupdatablefields.md
index cdf9171a46aed..3d8b5d115c8a2 100644
--- a/docs/development/core/public/kibana-plugin-core-public.appupdatablefields.md
+++ b/docs/development/core/public/kibana-plugin-core-public.appupdatablefields.md
@@ -9,5 +9,5 @@ Defines the list of fields that can be updated via an [AppUpdater](./kibana-plug
Signature:
```typescript
-export declare type AppUpdatableFields = Pick;
+export declare type AppUpdatableFields = Pick;
```
diff --git a/docs/development/core/public/kibana-plugin-core-public.chromenavlink.md b/docs/development/core/public/kibana-plugin-core-public.chromenavlink.md
index 1cc1a1194a537..a9fabb38df869 100644
--- a/docs/development/core/public/kibana-plugin-core-public.chromenavlink.md
+++ b/docs/development/core/public/kibana-plugin-core-public.chromenavlink.md
@@ -29,5 +29,5 @@ export interface ChromeNavLink
| [subUrlBase](./kibana-plugin-core-public.chromenavlink.suburlbase.md) | string | A url base that legacy apps can set to match deep URLs to an application. |
| [title](./kibana-plugin-core-public.chromenavlink.title.md) | string | The title of the application. |
| [tooltip](./kibana-plugin-core-public.chromenavlink.tooltip.md) | string | A tooltip shown when hovering over an app link. |
-| [url](./kibana-plugin-core-public.chromenavlink.url.md) | string | A url that legacy apps can set to deep link into their applications. |
+| [url](./kibana-plugin-core-public.chromenavlink.url.md) | string | The route used to open the [default path](./kibana-plugin-core-public.appbase.defaultpath.md) of an application. If unset, baseUrl will be used instead. |
diff --git a/docs/development/core/public/kibana-plugin-core-public.chromenavlink.url.md b/docs/development/core/public/kibana-plugin-core-public.chromenavlink.url.md
index 0c415ed1a7fad..1e0b890015993 100644
--- a/docs/development/core/public/kibana-plugin-core-public.chromenavlink.url.md
+++ b/docs/development/core/public/kibana-plugin-core-public.chromenavlink.url.md
@@ -4,11 +4,7 @@
## ChromeNavLink.url property
-> Warning: This API is now obsolete.
->
->
-
-A url that legacy apps can set to deep link into their applications.
+The route used to open the [default path](./kibana-plugin-core-public.appbase.defaultpath.md) of an application. If unset, `baseUrl` will be used instead.
Signature:
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectmigrationfn.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectmigrationfn.md
index a502c40db0cd8..a3294fb0a087a 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectmigrationfn.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectmigrationfn.md
@@ -9,22 +9,36 @@ A migration function for a [saved object type](./kibana-plugin-core-server.saved
Signature:
```typescript
-export declare type SavedObjectMigrationFn = (doc: SavedObjectUnsanitizedDoc, context: SavedObjectMigrationContext) => SavedObjectUnsanitizedDoc;
+export declare type SavedObjectMigrationFn = (doc: SavedObjectUnsanitizedDoc, context: SavedObjectMigrationContext) => SavedObjectUnsanitizedDoc;
```
## Example
```typescript
-const migrateProperty: SavedObjectMigrationFn = (doc, { log }) => {
- if(doc.attributes.someProp === null) {
- log.warn('Skipping migration');
- } else {
- doc.attributes.someProp = migrateProperty(doc.attributes.someProp);
- }
-
- return doc;
+interface TypeV1Attributes {
+ someKey: string;
+ obsoleteProperty: number;
}
+interface TypeV2Attributes {
+ someKey: string;
+ newProperty: string;
+}
+
+const migrateToV2: SavedObjectMigrationFn = (doc, { log }) => {
+ const { obsoleteProperty, ...otherAttributes } = doc.attributes;
+ // instead of mutating `doc` we make a shallow copy so that we can use separate types for the input
+ // and output attributes. We don't need to make a deep copy, we just need to ensure that obsolete
+ // attributes are not present on the returned doc.
+ return {
+ ...doc,
+ attributes: {
+ ...otherAttributes,
+ newProperty: migrate(obsoleteProperty),
+ },
+ };
+};
+
```
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsanitizeddoc.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsanitizeddoc.md
index 6d4e252fe7532..3f4090619edbf 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsanitizeddoc.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsanitizeddoc.md
@@ -9,5 +9,5 @@ Describes Saved Object documents that have passed through the migration framewor
Signature:
```typescript
-export declare type SavedObjectSanitizedDoc = SavedObjectDoc & Referencable;
+export declare type SavedObjectSanitizedDoc = SavedObjectDoc & Referencable;
```
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectunsanitizeddoc.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectunsanitizeddoc.md
index be51400addbbc..8e2395ee6310d 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectunsanitizeddoc.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectunsanitizeddoc.md
@@ -9,5 +9,5 @@ Describes Saved Object documents from Kibana < 7.0.0 which don't have a `refe
Signature:
```typescript
-export declare type SavedObjectUnsanitizedDoc = SavedObjectDoc & Partial;
+export declare type SavedObjectUnsanitizedDoc = SavedObjectDoc & Partial;
```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.agggrouplabels.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.agggrouplabels.md
new file mode 100644
index 0000000000000..6684ba8546f85
--- /dev/null
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.agggrouplabels.md
@@ -0,0 +1,15 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggGroupLabels](./kibana-plugin-plugins-data-public.agggrouplabels.md)
+
+## AggGroupLabels variable
+
+Signature:
+
+```typescript
+AggGroupLabels: {
+ [AggGroupNames.Buckets]: string;
+ [AggGroupNames.Metrics]: string;
+ [AggGroupNames.None]: string;
+}
+```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.agggroupname.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.agggroupname.md
new file mode 100644
index 0000000000000..d4476398680a8
--- /dev/null
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.agggroupname.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggGroupName](./kibana-plugin-plugins-data-public.agggroupname.md)
+
+## AggGroupName type
+
+Signature:
+
+```typescript
+export declare type AggGroupName = $Values;
+```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefieldfilters.addfilter.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefieldfilters.addfilter.md
deleted file mode 100644
index c9d6772a13b8d..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefieldfilters.addfilter.md
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggTypeFieldFilters](./kibana-plugin-plugins-data-public.aggtypefieldfilters.md) > [addFilter](./kibana-plugin-plugins-data-public.aggtypefieldfilters.addfilter.md)
-
-## AggTypeFieldFilters.addFilter() method
-
-Register a new with this registry. This will be used by the .
-
-Signature:
-
-```typescript
-addFilter(filter: AggTypeFieldFilter): void;
-```
-
-## Parameters
-
-| Parameter | Type | Description |
-| --- | --- | --- |
-| filter | AggTypeFieldFilter | |
-
-Returns:
-
-`void`
-
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefieldfilters.filter.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefieldfilters.filter.md
deleted file mode 100644
index 038c339bf6774..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefieldfilters.filter.md
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggTypeFieldFilters](./kibana-plugin-plugins-data-public.aggtypefieldfilters.md) > [filter](./kibana-plugin-plugins-data-public.aggtypefieldfilters.filter.md)
-
-## AggTypeFieldFilters.filter() method
-
-Returns the filtered by all registered filters.
-
-Signature:
-
-```typescript
-filter(fields: IndexPatternField[], aggConfig: IAggConfig): IndexPatternField[];
-```
-
-## Parameters
-
-| Parameter | Type | Description |
-| --- | --- | --- |
-| fields | IndexPatternField[] | |
-| aggConfig | IAggConfig | |
-
-Returns:
-
-`IndexPatternField[]`
-
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefieldfilters.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefieldfilters.md
deleted file mode 100644
index c0b386efbf9c7..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefieldfilters.md
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggTypeFieldFilters](./kibana-plugin-plugins-data-public.aggtypefieldfilters.md)
-
-## AggTypeFieldFilters class
-
-A registry to store which are used to filter down available fields for a specific visualization and .
-
-Signature:
-
-```typescript
-declare class AggTypeFieldFilters
-```
-
-## Methods
-
-| Method | Modifiers | Description |
-| --- | --- | --- |
-| [addFilter(filter)](./kibana-plugin-plugins-data-public.aggtypefieldfilters.addfilter.md) | | Register a new with this registry. This will be used by the . |
-| [filter(fields, aggConfig)](./kibana-plugin-plugins-data-public.aggtypefieldfilters.filter.md) | | Returns the filtered by all registered filters. |
-
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefilters.addfilter.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefilters.addfilter.md
deleted file mode 100644
index 9df003377c4a1..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefilters.addfilter.md
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggTypeFilters](./kibana-plugin-plugins-data-public.aggtypefilters.md) > [addFilter](./kibana-plugin-plugins-data-public.aggtypefilters.addfilter.md)
-
-## AggTypeFilters.addFilter() method
-
-Register a new with this registry.
-
-Signature:
-
-```typescript
-addFilter(filter: AggTypeFilter): void;
-```
-
-## Parameters
-
-| Parameter | Type | Description |
-| --- | --- | --- |
-| filter | AggTypeFilter | |
-
-Returns:
-
-`void`
-
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefilters.filter.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefilters.filter.md
deleted file mode 100644
index 81e6e9b95d655..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefilters.filter.md
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggTypeFilters](./kibana-plugin-plugins-data-public.aggtypefilters.md) > [filter](./kibana-plugin-plugins-data-public.aggtypefilters.filter.md)
-
-## AggTypeFilters.filter() method
-
-Returns the filtered by all registered filters.
-
-Signature:
-
-```typescript
-filter(aggTypes: IAggType[], indexPattern: IndexPattern, aggConfig: IAggConfig, aggFilter: string[]): IAggType[];
-```
-
-## Parameters
-
-| Parameter | Type | Description |
-| --- | --- | --- |
-| aggTypes | IAggType[] | |
-| indexPattern | IndexPattern | |
-| aggConfig | IAggConfig | |
-| aggFilter | string[] | |
-
-Returns:
-
-`IAggType[]`
-
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefilters.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefilters.md
deleted file mode 100644
index c5e24bc0a78a0..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggtypefilters.md
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggTypeFilters](./kibana-plugin-plugins-data-public.aggtypefilters.md)
-
-## AggTypeFilters class
-
-A registry to store which are used to filter down available aggregations for a specific visualization and .
-
-Signature:
-
-```typescript
-declare class AggTypeFilters
-```
-
-## Methods
-
-| Method | Modifiers | Description |
-| --- | --- | --- |
-| [addFilter(filter)](./kibana-plugin-plugins-data-public.aggtypefilters.addfilter.md) | | Register a new with this registry. |
-| [filter(aggTypes, indexPattern, aggConfig, aggFilter)](./kibana-plugin-plugins-data-public.aggtypefilters.filter.md) | | Returns the filtered by all registered filters. |
-
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.daterangekey.from.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.daterangekey.from.md
deleted file mode 100644
index 245269af366bc..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.daterangekey.from.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [DateRangeKey](./kibana-plugin-plugins-data-public.daterangekey.md) > [from](./kibana-plugin-plugins-data-public.daterangekey.from.md)
-
-## DateRangeKey.from property
-
-Signature:
-
-```typescript
-from: number;
-```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.daterangekey.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.daterangekey.md
deleted file mode 100644
index 540d429dced48..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.daterangekey.md
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [DateRangeKey](./kibana-plugin-plugins-data-public.daterangekey.md)
-
-## DateRangeKey interface
-
-Signature:
-
-```typescript
-export interface DateRangeKey
-```
-
-## Properties
-
-| Property | Type | Description |
-| --- | --- | --- |
-| [from](./kibana-plugin-plugins-data-public.daterangekey.from.md) | number | |
-| [to](./kibana-plugin-plugins-data-public.daterangekey.to.md) | number | |
-
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.daterangekey.to.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.daterangekey.to.md
deleted file mode 100644
index 024a6c2105427..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.daterangekey.to.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [DateRangeKey](./kibana-plugin-plugins-data-public.daterangekey.md) > [to](./kibana-plugin-plugins-data-public.daterangekey.to.md)
-
-## DateRangeKey.to property
-
-Signature:
-
-```typescript
-to: number;
-```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iagggroupnames.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iagggroupnames.md
deleted file mode 100644
index 07310a4219359..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iagggroupnames.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IAggGroupNames](./kibana-plugin-plugins-data-public.iagggroupnames.md)
-
-## IAggGroupNames type
-
-Signature:
-
-```typescript
-export declare type IAggGroupNames = $Values;
-```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iprangekey.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iprangekey.md
deleted file mode 100644
index 96903a5df9844..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iprangekey.md
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IpRangeKey](./kibana-plugin-plugins-data-public.iprangekey.md)
-
-## IpRangeKey type
-
-Signature:
-
-```typescript
-export declare type IpRangeKey = {
- type: 'mask';
- mask: string;
-} | {
- type: 'range';
- from: string;
- to: string;
-};
-```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md
index e1df493143b73..13e38ba5e6e5d 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md
@@ -9,8 +9,6 @@
| Class | Description |
| --- | --- |
| [AggParamType](./kibana-plugin-plugins-data-public.aggparamtype.md) | |
-| [AggTypeFieldFilters](./kibana-plugin-plugins-data-public.aggtypefieldfilters.md) | A registry to store which are used to filter down available fields for a specific visualization and . |
-| [AggTypeFilters](./kibana-plugin-plugins-data-public.aggtypefilters.md) | A registry to store which are used to filter down available aggregations for a specific visualization and . |
| [Field](./kibana-plugin-plugins-data-public.field.md) | |
| [FieldFormat](./kibana-plugin-plugins-data-public.fieldformat.md) | |
| [FilterManager](./kibana-plugin-plugins-data-public.filtermanager.md) | |
@@ -53,7 +51,6 @@
| [AggParamOption](./kibana-plugin-plugins-data-public.aggparamoption.md) | |
| [DataPublicPluginSetup](./kibana-plugin-plugins-data-public.datapublicpluginsetup.md) | |
| [DataPublicPluginStart](./kibana-plugin-plugins-data-public.datapublicpluginstart.md) | |
-| [DateRangeKey](./kibana-plugin-plugins-data-public.daterangekey.md) | |
| [EsQueryConfig](./kibana-plugin-plugins-data-public.esqueryconfig.md) | |
| [FetchOptions](./kibana-plugin-plugins-data-public.fetchoptions.md) | |
| [FieldFormatConfig](./kibana-plugin-plugins-data-public.fieldformatconfig.md) | |
@@ -75,7 +72,6 @@
| [ISearchStrategy](./kibana-plugin-plugins-data-public.isearchstrategy.md) | Search strategy interface contains a search method that takes in a request and returns a promise that resolves to a response. |
| [ISyncSearchRequest](./kibana-plugin-plugins-data-public.isyncsearchrequest.md) | |
| [KueryNode](./kibana-plugin-plugins-data-public.kuerynode.md) | |
-| [OptionedParamEditorProps](./kibana-plugin-plugins-data-public.optionedparameditorprops.md) | |
| [OptionedValueProp](./kibana-plugin-plugins-data-public.optionedvalueprop.md) | |
| [Query](./kibana-plugin-plugins-data-public.query.md) | |
| [QueryState](./kibana-plugin-plugins-data-public.querystate.md) | All query state service state |
@@ -95,6 +91,7 @@
| Variable | Description |
| --- | --- |
+| [AggGroupLabels](./kibana-plugin-plugins-data-public.agggrouplabels.md) | |
| [AggGroupNames](./kibana-plugin-plugins-data-public.agggroupnames.md) | |
| [baseFormattersPublic](./kibana-plugin-plugins-data-public.baseformatterspublic.md) | |
| [castEsToKbnFieldTypeName](./kibana-plugin-plugins-data-public.castestokbnfieldtypename.md) | Get the KbnFieldType name for an esType string |
@@ -119,6 +116,7 @@
| Type Alias | Description |
| --- | --- |
| [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) | |
+| [AggGroupName](./kibana-plugin-plugins-data-public.agggroupname.md) | |
| [AggParam](./kibana-plugin-plugins-data-public.aggparam.md) | |
| [CustomFilter](./kibana-plugin-plugins-data-public.customfilter.md) | |
| [EsQuerySortValue](./kibana-plugin-plugins-data-public.esquerysortvalue.md) | |
@@ -127,7 +125,6 @@
| [FieldFormatsContentType](./kibana-plugin-plugins-data-public.fieldformatscontenttype.md) | \* |
| [FieldFormatsGetConfigFn](./kibana-plugin-plugins-data-public.fieldformatsgetconfigfn.md) | |
| [IAggConfig](./kibana-plugin-plugins-data-public.iaggconfig.md) | AggConfig This class represents an aggregation, which is displayed in the left-hand nav of the Visualize app. |
-| [IAggGroupNames](./kibana-plugin-plugins-data-public.iagggroupnames.md) | |
| [IAggType](./kibana-plugin-plugins-data-public.iaggtype.md) | |
| [IFieldFormat](./kibana-plugin-plugins-data-public.ifieldformat.md) | |
| [IFieldFormatsRegistry](./kibana-plugin-plugins-data-public.ifieldformatsregistry.md) | |
@@ -136,7 +133,6 @@
| [IndexPatternAggRestrictions](./kibana-plugin-plugins-data-public.indexpatternaggrestrictions.md) | |
| [IndexPatternsContract](./kibana-plugin-plugins-data-public.indexpatternscontract.md) | |
| [InputTimeRange](./kibana-plugin-plugins-data-public.inputtimerange.md) | |
-| [IpRangeKey](./kibana-plugin-plugins-data-public.iprangekey.md) | |
| [ISearch](./kibana-plugin-plugins-data-public.isearch.md) | |
| [ISearchGeneric](./kibana-plugin-plugins-data-public.isearchgeneric.md) | |
| [ISearchSource](./kibana-plugin-plugins-data-public.isearchsource.md) | \* |
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.optionedparameditorprops.aggparam.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.optionedparameditorprops.aggparam.md
deleted file mode 100644
index 68e4371acc2f3..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.optionedparameditorprops.aggparam.md
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [OptionedParamEditorProps](./kibana-plugin-plugins-data-public.optionedparameditorprops.md) > [aggParam](./kibana-plugin-plugins-data-public.optionedparameditorprops.aggparam.md)
-
-## OptionedParamEditorProps.aggParam property
-
-Signature:
-
-```typescript
-aggParam: {
- options: T[];
- };
-```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.optionedparameditorprops.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.optionedparameditorprops.md
deleted file mode 100644
index 00a440a0a775a..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.optionedparameditorprops.md
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [OptionedParamEditorProps](./kibana-plugin-plugins-data-public.optionedparameditorprops.md)
-
-## OptionedParamEditorProps interface
-
-Signature:
-
-```typescript
-export interface OptionedParamEditorProps
-```
-
-## Properties
-
-| Property | Type | Description |
-| --- | --- | --- |
-| [aggParam](./kibana-plugin-plugins-data-public.optionedparameditorprops.aggparam.md) | { options: T[]; } | |
-
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.search.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.search.md
index 9a22339fd0530..67c4eac67a9e6 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.search.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.search.md
@@ -9,12 +9,7 @@
```typescript
search: {
aggs: {
- AggConfigs: typeof AggConfigs;
- aggGroupNamesMap: () => Record<"metrics" | "buckets", string>;
- aggTypeFilters: import("./search/aggs/filter/agg_type_filters").AggTypeFilters;
CidrMask: typeof CidrMask;
- convertDateRangeToString: typeof convertDateRangeToString;
- convertIPRangeToString: (range: import("./search").IpRangeKey, format: (val: any) => string) => string;
dateHistogramInterval: typeof dateHistogramInterval;
intervalOptions: ({
display: string;
diff --git a/src/cli/cluster/cluster_manager.ts b/src/cli/cluster/cluster_manager.ts
index 32a23d74dbda4..97dec3eead303 100644
--- a/src/cli/cluster/cluster_manager.ts
+++ b/src/cli/cluster/cluster_manager.ts
@@ -259,13 +259,15 @@ export class ClusterManager {
const ignorePaths = [
/[\\\/](\..*|node_modules|bower_components|target|public|__[a-z0-9_]+__|coverage)([\\\/]|$)/,
- /\.test\.(js|ts)$/,
+ /\.test\.(js|tsx?)$/,
+ /\.md$/,
+ /debug\.log$/,
...pluginInternalDirsIgnore,
fromRoot('src/legacy/server/sass/__tmp__'),
fromRoot('x-pack/legacy/plugins/reporting/.chromium'),
fromRoot('x-pack/plugins/siem/cypress'),
- fromRoot('x-pack/legacy/plugins/apm/e2e'),
- fromRoot('x-pack/legacy/plugins/apm/scripts'),
+ fromRoot('x-pack/plugins/apm/e2e'),
+ fromRoot('x-pack/plugins/apm/scripts'),
fromRoot('x-pack/legacy/plugins/canvas/canvas_plugin_src'), // prevents server from restarting twice for Canvas plugin changes,
'plugins/java_languageserver',
];
diff --git a/src/core/MIGRATION_EXAMPLES.md b/src/core/MIGRATION_EXAMPLES.md
index 8c5fe4875aaea..c91c00bc1aa02 100644
--- a/src/core/MIGRATION_EXAMPLES.md
+++ b/src/core/MIGRATION_EXAMPLES.md
@@ -957,7 +957,7 @@ const migration = (doc, log) => {...}
Would be converted to:
```typescript
-const migration: SavedObjectMigrationFn = (doc, { log }) => {...}
+const migration: SavedObjectMigrationFn = (doc, { log }) => {...}
```
### Remarks
diff --git a/src/core/public/application/application_service.test.ts b/src/core/public/application/application_service.test.ts
index c25918c6b7328..e29837aecb125 100644
--- a/src/core/public/application/application_service.test.ts
+++ b/src/core/public/application/application_service.test.ts
@@ -87,7 +87,7 @@ describe('#setup()', () => {
).toThrowErrorMatchingInlineSnapshot(`"Applications cannot be registered after \\"setup\\""`);
});
- it('allows to register a statusUpdater for the application', async () => {
+ it('allows to register an AppUpdater for the application', async () => {
const setup = service.setup(setupDeps);
const pluginId = Symbol('plugin');
@@ -118,6 +118,7 @@ describe('#setup()', () => {
updater$.next(app => ({
status: AppStatus.inaccessible,
tooltip: 'App inaccessible due to reason',
+ defaultPath: 'foo/bar',
}));
applications = await applications$.pipe(take(1)).toPromise();
@@ -128,6 +129,7 @@ describe('#setup()', () => {
legacy: false,
navLinkStatus: AppNavLinkStatus.default,
status: AppStatus.inaccessible,
+ defaultPath: 'foo/bar',
tooltip: 'App inaccessible due to reason',
})
);
@@ -209,7 +211,7 @@ describe('#setup()', () => {
});
});
- describe('registerAppStatusUpdater', () => {
+ describe('registerAppUpdater', () => {
it('updates status fields', async () => {
const setup = service.setup(setupDeps);
@@ -413,6 +415,36 @@ describe('#setup()', () => {
})
);
});
+
+ it('allows to update the basePath', async () => {
+ const setup = service.setup(setupDeps);
+
+ const pluginId = Symbol('plugin');
+ setup.register(pluginId, createApp({ id: 'app1' }));
+
+ const updater = new BehaviorSubject(app => ({}));
+ setup.registerAppUpdater(updater);
+
+ const start = await service.start(startDeps);
+ await start.navigateToApp('app1');
+ expect(MockHistory.push).toHaveBeenCalledWith('/app/app1', undefined);
+ MockHistory.push.mockClear();
+
+ updater.next(app => ({ defaultPath: 'default-path' }));
+ await start.navigateToApp('app1');
+ expect(MockHistory.push).toHaveBeenCalledWith('/app/app1/default-path', undefined);
+ MockHistory.push.mockClear();
+
+ updater.next(app => ({ defaultPath: 'another-path' }));
+ await start.navigateToApp('app1');
+ expect(MockHistory.push).toHaveBeenCalledWith('/app/app1/another-path', undefined);
+ MockHistory.push.mockClear();
+
+ updater.next(app => ({}));
+ await start.navigateToApp('app1');
+ expect(MockHistory.push).toHaveBeenCalledWith('/app/app1', undefined);
+ MockHistory.push.mockClear();
+ });
});
it("`registerMountContext` calls context container's registerContext", () => {
@@ -676,6 +708,57 @@ describe('#start()', () => {
expect(MockHistory.push).toHaveBeenCalledWith('/custom/path#/hash/router/path', undefined);
});
+ it('preserves trailing slash when path contains a hash', async () => {
+ const { register } = service.setup(setupDeps);
+
+ register(Symbol(), createApp({ id: 'app2', appRoute: '/custom/app-path' }));
+
+ const { navigateToApp } = await service.start(startDeps);
+ await navigateToApp('app2', { path: '#/' });
+ expect(MockHistory.push).toHaveBeenCalledWith('/custom/app-path#/', undefined);
+ MockHistory.push.mockClear();
+
+ await navigateToApp('app2', { path: '#/foo/bar/' });
+ expect(MockHistory.push).toHaveBeenCalledWith('/custom/app-path#/foo/bar/', undefined);
+ MockHistory.push.mockClear();
+
+ await navigateToApp('app2', { path: '/path#/' });
+ expect(MockHistory.push).toHaveBeenCalledWith('/custom/app-path/path#/', undefined);
+ MockHistory.push.mockClear();
+
+ await navigateToApp('app2', { path: '/path#/hash/' });
+ expect(MockHistory.push).toHaveBeenCalledWith('/custom/app-path/path#/hash/', undefined);
+ MockHistory.push.mockClear();
+
+ await navigateToApp('app2', { path: '/path/' });
+ expect(MockHistory.push).toHaveBeenCalledWith('/custom/app-path/path', undefined);
+ MockHistory.push.mockClear();
+ });
+
+ it('appends the defaultPath when the path parameter is not specified', async () => {
+ const { register } = service.setup(setupDeps);
+
+ register(Symbol(), createApp({ id: 'app1', defaultPath: 'default/path' }));
+ register(
+ Symbol(),
+ createApp({ id: 'app2', appRoute: '/custom-app-path', defaultPath: '/my-base' })
+ );
+
+ const { navigateToApp } = await service.start(startDeps);
+
+ await navigateToApp('app1', { path: 'defined-path' });
+ expect(MockHistory.push).toHaveBeenCalledWith('/app/app1/defined-path', undefined);
+
+ await navigateToApp('app1', {});
+ expect(MockHistory.push).toHaveBeenCalledWith('/app/app1/default/path', undefined);
+
+ await navigateToApp('app2', { path: 'defined-path' });
+ expect(MockHistory.push).toHaveBeenCalledWith('/custom-app-path/defined-path', undefined);
+
+ await navigateToApp('app2', {});
+ expect(MockHistory.push).toHaveBeenCalledWith('/custom-app-path/my-base', undefined);
+ });
+
it('includes state if specified', async () => {
const { register } = service.setup(setupDeps);
diff --git a/src/core/public/application/application_service.tsx b/src/core/public/application/application_service.tsx
index 1c9492d81c7f6..bafa1932e5e92 100644
--- a/src/core/public/application/application_service.tsx
+++ b/src/core/public/application/application_service.tsx
@@ -46,6 +46,7 @@ import {
Mounter,
} from './types';
import { getLeaveAction, isConfirmAction } from './application_leave';
+import { appendAppPath } from './utils';
interface SetupDeps {
context: ContextSetup;
@@ -81,13 +82,7 @@ const getAppUrl = (mounters: Map, appId: string, path: string =
const appBasePath = mounters.get(appId)?.appRoute
? `/${mounters.get(appId)!.appRoute}`
: `/app/${appId}`;
-
- // Only preppend slash if not a hash or query path
- path = path.startsWith('#') || path.startsWith('?') ? path : `/${path}`;
-
- return `${appBasePath}${path}`
- .replace(/\/{2,}/g, '/') // Remove duplicate slashes
- .replace(/\/$/, ''); // Remove trailing slash
+ return appendAppPath(appBasePath, path);
};
const allApplicationsFilter = '__ALL__';
@@ -290,6 +285,9 @@ export class ApplicationService {
},
navigateToApp: async (appId, { path, state }: { path?: string; state?: any } = {}) => {
if (await this.shouldNavigate(overlays)) {
+ if (path === undefined) {
+ path = applications$.value.get(appId)?.defaultPath;
+ }
this.appLeaveHandlers.delete(this.currentAppId$.value!);
this.navigate!(getAppUrl(availableMounters, appId, path), state);
this.currentAppId$.next(appId);
diff --git a/src/core/public/application/types.ts b/src/core/public/application/types.ts
index 318afb652999e..0734e178033e2 100644
--- a/src/core/public/application/types.ts
+++ b/src/core/public/application/types.ts
@@ -66,6 +66,13 @@ export interface AppBase {
*/
navLinkStatus?: AppNavLinkStatus;
+ /**
+ * Allow to define the default path a user should be directed to when navigating to the app.
+ * When defined, this value will be used as a default for the `path` option when calling {@link ApplicationStart.navigateToApp | navigateToApp}`,
+ * and will also be appended to the {@link ChromeNavLink | application navLink} in the navigation bar.
+ */
+ defaultPath?: string;
+
/**
* An {@link AppUpdater} observable that can be used to update the application {@link AppUpdatableFields} at runtime.
*
@@ -187,7 +194,10 @@ export enum AppNavLinkStatus {
* Defines the list of fields that can be updated via an {@link AppUpdater}.
* @public
*/
-export type AppUpdatableFields = Pick;
+export type AppUpdatableFields = Pick<
+ AppBase,
+ 'status' | 'navLinkStatus' | 'tooltip' | 'defaultPath'
+>;
/**
* Updater for applications.
@@ -642,7 +652,8 @@ export interface ApplicationStart {
* Navigate to a given app
*
* @param appId
- * @param options.path - optional path inside application to deep link to
+ * @param options.path - optional path inside application to deep link to.
+ * If undefined, will use {@link AppBase.defaultPath | the app's default path}` as default.
* @param options.state - optional state to forward to the application
*/
navigateToApp(appId: string, options?: { path?: string; state?: any }): Promise;
diff --git a/src/core/public/application/utils.test.ts b/src/core/public/application/utils.test.ts
new file mode 100644
index 0000000000000..7ed0919f88c61
--- /dev/null
+++ b/src/core/public/application/utils.test.ts
@@ -0,0 +1,71 @@
+/*
+ * 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 { removeSlashes, appendAppPath } from './utils';
+
+describe('removeSlashes', () => {
+ it('only removes duplicates by default', () => {
+ expect(removeSlashes('/some//url//to//')).toEqual('/some/url/to/');
+ expect(removeSlashes('some/////other//url')).toEqual('some/other/url');
+ });
+
+ it('remove trailing slash when `trailing` is true', () => {
+ expect(removeSlashes('/some//url//to//', { trailing: true })).toEqual('/some/url/to');
+ });
+
+ it('remove leading slash when `leading` is true', () => {
+ expect(removeSlashes('/some//url//to//', { leading: true })).toEqual('some/url/to/');
+ });
+
+ it('does not removes duplicates when `duplicates` is false', () => {
+ expect(removeSlashes('/some//url//to/', { leading: true, duplicates: false })).toEqual(
+ 'some//url//to/'
+ );
+ expect(removeSlashes('/some//url//to/', { trailing: true, duplicates: false })).toEqual(
+ '/some//url//to'
+ );
+ });
+
+ it('accept mixed options', () => {
+ expect(
+ removeSlashes('/some//url//to/', { leading: true, duplicates: false, trailing: true })
+ ).toEqual('some//url//to');
+ expect(
+ removeSlashes('/some//url//to/', { leading: true, duplicates: true, trailing: true })
+ ).toEqual('some/url/to');
+ });
+});
+
+describe('appendAppPath', () => {
+ it('appends the appBasePath with given path', () => {
+ expect(appendAppPath('/app/my-app', '/some-path')).toEqual('/app/my-app/some-path');
+ expect(appendAppPath('/app/my-app/', 'some-path')).toEqual('/app/my-app/some-path');
+ expect(appendAppPath('/app/my-app', 'some-path')).toEqual('/app/my-app/some-path');
+ expect(appendAppPath('/app/my-app', '')).toEqual('/app/my-app');
+ });
+
+ it('preserves the trailing slash only if included in the hash', () => {
+ expect(appendAppPath('/app/my-app', '/some-path/')).toEqual('/app/my-app/some-path');
+ expect(appendAppPath('/app/my-app', '/some-path#/')).toEqual('/app/my-app/some-path#/');
+ expect(appendAppPath('/app/my-app', '/some-path#/hash/')).toEqual(
+ '/app/my-app/some-path#/hash/'
+ );
+ expect(appendAppPath('/app/my-app', '/some-path#/hash')).toEqual('/app/my-app/some-path#/hash');
+ });
+});
diff --git a/src/core/public/application/utils.ts b/src/core/public/application/utils.ts
new file mode 100644
index 0000000000000..048f195fe1223
--- /dev/null
+++ b/src/core/public/application/utils.ts
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+/**
+ * Utility to remove trailing, leading or duplicate slashes.
+ * By default will only remove duplicates.
+ */
+export const removeSlashes = (
+ url: string,
+ {
+ trailing = false,
+ leading = false,
+ duplicates = true,
+ }: { trailing?: boolean; leading?: boolean; duplicates?: boolean } = {}
+): string => {
+ if (duplicates) {
+ url = url.replace(/\/{2,}/g, '/');
+ }
+ if (trailing) {
+ url = url.replace(/\/$/, '');
+ }
+ if (leading) {
+ url = url.replace(/^\//, '');
+ }
+ return url;
+};
+
+export const appendAppPath = (appBasePath: string, path: string = '') => {
+ // Only prepend slash if not a hash or query path
+ path = path === '' || path.startsWith('#') || path.startsWith('?') ? path : `/${path}`;
+ // Do not remove trailing slash when in hashbang
+ const removeTrailing = path.indexOf('#') === -1;
+ return removeSlashes(`${appBasePath}${path}`, {
+ trailing: removeTrailing,
+ duplicates: true,
+ leading: false,
+ });
+};
diff --git a/src/core/public/chrome/nav_links/nav_link.ts b/src/core/public/chrome/nav_links/nav_link.ts
index d0ef2aeb265fe..fb2972735c2b7 100644
--- a/src/core/public/chrome/nav_links/nav_link.ts
+++ b/src/core/public/chrome/nav_links/nav_link.ts
@@ -44,6 +44,12 @@ export interface ChromeNavLink {
*/
readonly baseUrl: string;
+ /**
+ * The route used to open the {@link AppBase.defaultPath | default path } of an application.
+ * If unset, `baseUrl` will be used instead.
+ */
+ readonly url?: string;
+
/**
* An ordinal used to sort nav links relative to one another for display.
*/
@@ -99,18 +105,6 @@ export interface ChromeNavLink {
*/
readonly linkToLastSubUrl?: boolean;
- /**
- * A url that legacy apps can set to deep link into their applications.
- *
- * @internalRemarks
- * Currently used by the "lastSubUrl" feature legacy/ui/chrome. This should
- * be removed once the ApplicationService is implemented and mounting apps. At that
- * time, each app can handle opening to the previous location when they are mounted.
- *
- * @deprecated
- */
- readonly url?: string;
-
/**
* Indicates whether or not this app is currently on the screen.
*
diff --git a/src/core/public/chrome/nav_links/to_nav_link.test.ts b/src/core/public/chrome/nav_links/to_nav_link.test.ts
index 23fdabe0f3430..4c319873af804 100644
--- a/src/core/public/chrome/nav_links/to_nav_link.test.ts
+++ b/src/core/public/chrome/nav_links/to_nav_link.test.ts
@@ -85,6 +85,38 @@ describe('toNavLink', () => {
expect(link.properties.baseUrl).toEqual('http://localhost/base-path/my-route/my-path');
});
+ it('generates the `url` property', () => {
+ let link = toNavLink(
+ app({
+ appRoute: '/my-route/my-path',
+ }),
+ basePath
+ );
+ expect(link.properties.url).toEqual('http://localhost/base-path/my-route/my-path');
+
+ link = toNavLink(
+ app({
+ appRoute: '/my-route/my-path',
+ defaultPath: 'some/default/path',
+ }),
+ basePath
+ );
+ expect(link.properties.url).toEqual(
+ 'http://localhost/base-path/my-route/my-path/some/default/path'
+ );
+ });
+
+ it('does not generate `url` for legacy app', () => {
+ const link = toNavLink(
+ legacyApp({
+ appUrl: '/my-legacy-app/#foo',
+ defaultPath: '/some/default/path',
+ }),
+ basePath
+ );
+ expect(link.properties.url).toBeUndefined();
+ });
+
it('uses appUrl when converting legacy applications', () => {
expect(
toNavLink(
diff --git a/src/core/public/chrome/nav_links/to_nav_link.ts b/src/core/public/chrome/nav_links/to_nav_link.ts
index 18e4b7b26b6ba..f79b1df77f8e1 100644
--- a/src/core/public/chrome/nav_links/to_nav_link.ts
+++ b/src/core/public/chrome/nav_links/to_nav_link.ts
@@ -20,9 +20,11 @@
import { App, AppNavLinkStatus, AppStatus, LegacyApp } from '../../application';
import { IBasePath } from '../../http';
import { NavLinkWrapper } from './nav_link';
+import { appendAppPath } from '../../application/utils';
export function toNavLink(app: App | LegacyApp, basePath: IBasePath): NavLinkWrapper {
const useAppStatus = app.navLinkStatus === AppNavLinkStatus.default;
+ const baseUrl = isLegacyApp(app) ? basePath.prepend(app.appUrl) : basePath.prepend(app.appRoute!);
return new NavLinkWrapper({
...app,
hidden: useAppStatus
@@ -30,9 +32,12 @@ export function toNavLink(app: App | LegacyApp, basePath: IBasePath): NavLinkWra
: app.navLinkStatus === AppNavLinkStatus.hidden,
disabled: useAppStatus ? false : app.navLinkStatus === AppNavLinkStatus.disabled,
legacy: isLegacyApp(app),
- baseUrl: isLegacyApp(app)
- ? relativeToAbsolute(basePath.prepend(app.appUrl))
- : relativeToAbsolute(basePath.prepend(app.appRoute!)),
+ baseUrl: relativeToAbsolute(baseUrl),
+ ...(isLegacyApp(app)
+ ? {}
+ : {
+ url: relativeToAbsolute(appendAppPath(baseUrl, app.defaultPath)),
+ }),
});
}
diff --git a/src/core/public/chrome/ui/header/nav_link.tsx b/src/core/public/chrome/ui/header/nav_link.tsx
index 52b59c53b658c..d97ef477c2ee0 100644
--- a/src/core/public/chrome/ui/header/nav_link.tsx
+++ b/src/core/public/chrome/ui/header/nav_link.tsx
@@ -53,7 +53,7 @@ export function euiNavLink(
order,
tooltip,
} = navLink;
- let href = navLink.baseUrl;
+ let href = navLink.url ?? navLink.baseUrl;
if (legacy) {
href = url && !active ? url : baseUrl;
diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md
index b92bb209d2607..af06b207889c2 100644
--- a/src/core/public/public.api.md
+++ b/src/core/public/public.api.md
@@ -36,6 +36,7 @@ export interface AppBase {
capabilities?: Partial;
category?: AppCategory;
chromeless?: boolean;
+ defaultPath?: string;
euiIconType?: string;
icon?: string;
id: string;
@@ -168,7 +169,7 @@ export enum AppStatus {
export type AppUnmount = () => void;
// @public
-export type AppUpdatableFields = Pick;
+export type AppUpdatableFields = Pick;
// @public
export type AppUpdater = (app: AppBase) => Partial | undefined;
@@ -290,7 +291,6 @@ export interface ChromeNavLink {
readonly subUrlBase?: string;
readonly title: string;
readonly tooltip?: string;
- // @deprecated
readonly url?: string;
}
diff --git a/src/core/server/http/http_server.test.ts b/src/core/server/http/http_server.test.ts
index 27db79bb94d25..4fb433b5c77ba 100644
--- a/src/core/server/http/http_server.test.ts
+++ b/src/core/server/http/http_server.test.ts
@@ -1068,6 +1068,14 @@ describe('setup contract', () => {
await create();
expect(create()).rejects.toThrowError('A cookieSessionStorageFactory was already created');
});
+
+ it('does not throw if called after stop', async () => {
+ const { createCookieSessionStorageFactory } = await server.setup(config);
+ await server.stop();
+ expect(() => {
+ createCookieSessionStorageFactory(cookieOptions);
+ }).not.toThrow();
+ });
});
describe('#isTlsEnabled', () => {
@@ -1113,4 +1121,54 @@ describe('setup contract', () => {
expect(getServerInfo().protocol).toEqual('https');
});
});
+
+ describe('#registerStaticDir', () => {
+ it('does not throw if called after stop', async () => {
+ const { registerStaticDir } = await server.setup(config);
+ await server.stop();
+ expect(() => {
+ registerStaticDir('/path1/{path*}', '/path/to/resource');
+ }).not.toThrow();
+ });
+ });
+
+ describe('#registerOnPreAuth', () => {
+ test('does not throw if called after stop', async () => {
+ const { registerOnPreAuth } = await server.setup(config);
+ await server.stop();
+ expect(() => {
+ registerOnPreAuth((req, res) => res.unauthorized());
+ }).not.toThrow();
+ });
+ });
+
+ describe('#registerOnPostAuth', () => {
+ test('does not throw if called after stop', async () => {
+ const { registerOnPostAuth } = await server.setup(config);
+ await server.stop();
+ expect(() => {
+ registerOnPostAuth((req, res) => res.unauthorized());
+ }).not.toThrow();
+ });
+ });
+
+ describe('#registerOnPreResponse', () => {
+ test('does not throw if called after stop', async () => {
+ const { registerOnPreResponse } = await server.setup(config);
+ await server.stop();
+ expect(() => {
+ registerOnPreResponse((req, res, t) => t.next());
+ }).not.toThrow();
+ });
+ });
+
+ describe('#registerAuth', () => {
+ test('does not throw if called after stop', async () => {
+ const { registerAuth } = await server.setup(config);
+ await server.stop();
+ expect(() => {
+ registerAuth((req, res) => res.unauthorized());
+ }).not.toThrow();
+ });
+ });
});
diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts
index 77d3d99fb48cb..92ac5220735a1 100644
--- a/src/core/server/http/http_server.ts
+++ b/src/core/server/http/http_server.ts
@@ -74,6 +74,7 @@ export class HttpServer {
private registeredRouters = new Set();
private authRegistered = false;
private cookieSessionStorageCreated = false;
+ private stopped = false;
private readonly log: Logger;
private readonly authState: AuthStateStorage;
@@ -144,6 +145,10 @@ export class HttpServer {
if (this.server === undefined) {
throw new Error('Http server is not setup up yet');
}
+ if (this.stopped) {
+ this.log.warn(`start called after stop`);
+ return;
+ }
this.log.debug('starting http server');
for (const router of this.registeredRouters) {
@@ -189,13 +194,13 @@ export class HttpServer {
}
public async stop() {
+ this.stopped = true;
if (this.server === undefined) {
return;
}
this.log.debug('stopping http server');
await this.server.stop();
- this.server = undefined;
}
private getAuthOption(
@@ -234,6 +239,9 @@ export class HttpServer {
if (this.server === undefined) {
throw new Error('Server is not created yet');
}
+ if (this.stopped) {
+ this.log.warn(`setupConditionalCompression called after stop`);
+ }
const { enabled, referrerWhitelist: list } = config.compression;
if (!enabled) {
@@ -261,6 +269,9 @@ export class HttpServer {
if (this.server === undefined) {
throw new Error('Server is not created yet');
}
+ if (this.stopped) {
+ this.log.warn(`registerOnPostAuth called after stop`);
+ }
this.server.ext('onPostAuth', adoptToHapiOnPostAuthFormat(fn, this.log));
}
@@ -269,6 +280,9 @@ export class HttpServer {
if (this.server === undefined) {
throw new Error('Server is not created yet');
}
+ if (this.stopped) {
+ this.log.warn(`registerOnPreAuth called after stop`);
+ }
this.server.ext('onRequest', adoptToHapiOnPreAuthFormat(fn, this.log));
}
@@ -277,6 +291,9 @@ export class HttpServer {
if (this.server === undefined) {
throw new Error('Server is not created yet');
}
+ if (this.stopped) {
+ this.log.warn(`registerOnPreResponse called after stop`);
+ }
this.server.ext('onPreResponse', adoptToHapiOnPreResponseFormat(fn, this.log));
}
@@ -288,6 +305,9 @@ export class HttpServer {
if (this.server === undefined) {
throw new Error('Server is not created yet');
}
+ if (this.stopped) {
+ this.log.warn(`createCookieSessionStorageFactory called after stop`);
+ }
if (this.cookieSessionStorageCreated) {
throw new Error('A cookieSessionStorageFactory was already created');
}
@@ -305,6 +325,9 @@ export class HttpServer {
if (this.server === undefined) {
throw new Error('Server is not created yet');
}
+ if (this.stopped) {
+ this.log.warn(`registerAuth called after stop`);
+ }
if (this.authRegistered) {
throw new Error('Auth interceptor was already registered');
}
@@ -348,6 +371,9 @@ export class HttpServer {
if (this.server === undefined) {
throw new Error('Http server is not setup up yet');
}
+ if (this.stopped) {
+ this.log.warn(`registerStaticDir called after stop`);
+ }
this.server.route({
path,
diff --git a/src/core/server/saved_objects/migrations/core/index.ts b/src/core/server/saved_objects/migrations/core/index.ts
index 466d399f653cd..f7274740ea5fe 100644
--- a/src/core/server/saved_objects/migrations/core/index.ts
+++ b/src/core/server/saved_objects/migrations/core/index.ts
@@ -21,5 +21,5 @@ export { DocumentMigrator } from './document_migrator';
export { IndexMigrator } from './index_migrator';
export { buildActiveMappings } from './build_active_mappings';
export { CallCluster } from './call_cluster';
-export { LogFn } from './migration_logger';
+export { LogFn, SavedObjectsMigrationLogger } from './migration_logger';
export { MigrationResult, MigrationStatus } from './migration_coordinator';
diff --git a/src/legacy/server/config/explode_by.js b/src/core/server/saved_objects/migrations/mocks.ts
similarity index 60%
rename from src/legacy/server/config/explode_by.js
rename to src/core/server/saved_objects/migrations/mocks.ts
index 46347feca550d..76a890d26bfa0 100644
--- a/src/legacy/server/config/explode_by.js
+++ b/src/core/server/saved_objects/migrations/mocks.ts
@@ -17,21 +17,27 @@
* under the License.
*/
-import _ from 'lodash';
+import { SavedObjectMigrationContext } from './types';
+import { SavedObjectsMigrationLogger } from './core';
-export default function(dot, flatObject) {
- const fullObject = {};
- _.each(flatObject, function(value, key) {
- const keys = key.split(dot);
- (function walk(memo, keys, value) {
- const _key = keys.shift();
- if (keys.length === 0) {
- memo[_key] = value;
- } else {
- if (!memo[_key]) memo[_key] = {};
- walk(memo[_key], keys, value);
- }
- })(fullObject, keys, value);
- });
- return fullObject;
-}
+const createLoggerMock = (): jest.Mocked => {
+ const mock = {
+ debug: jest.fn(),
+ info: jest.fn(),
+ warning: jest.fn(),
+ warn: jest.fn(),
+ };
+
+ return mock;
+};
+
+const createContextMock = (): jest.Mocked => {
+ const mock = {
+ log: createLoggerMock(),
+ };
+ return mock;
+};
+
+export const migrationMocks = {
+ createContext: createContextMock,
+};
diff --git a/src/core/server/saved_objects/migrations/types.ts b/src/core/server/saved_objects/migrations/types.ts
index 6bc085dde872e..85f15b4c18b66 100644
--- a/src/core/server/saved_objects/migrations/types.ts
+++ b/src/core/server/saved_objects/migrations/types.ts
@@ -26,23 +26,37 @@ import { SavedObjectsMigrationLogger } from './core/migration_logger';
*
* @example
* ```typescript
- * const migrateProperty: SavedObjectMigrationFn = (doc, { log }) => {
- * if(doc.attributes.someProp === null) {
- * log.warn('Skipping migration');
- * } else {
- * doc.attributes.someProp = migrateProperty(doc.attributes.someProp);
- * }
+ * interface TypeV1Attributes {
+ * someKey: string;
+ * obsoleteProperty: number;
+ * }
*
- * return doc;
+ * interface TypeV2Attributes {
+ * someKey: string;
+ * newProperty: string;
* }
+ *
+ * const migrateToV2: SavedObjectMigrationFn = (doc, { log }) => {
+ * const { obsoleteProperty, ...otherAttributes } = doc.attributes;
+ * // instead of mutating `doc` we make a shallow copy so that we can use separate types for the input
+ * // and output attributes. We don't need to make a deep copy, we just need to ensure that obsolete
+ * // attributes are not present on the returned doc.
+ * return {
+ * ...doc,
+ * attributes: {
+ * ...otherAttributes,
+ * newProperty: migrate(obsoleteProperty),
+ * },
+ * };
+ * };
* ```
*
* @public
*/
-export type SavedObjectMigrationFn = (
- doc: SavedObjectUnsanitizedDoc,
+export type SavedObjectMigrationFn = (
+ doc: SavedObjectUnsanitizedDoc,
context: SavedObjectMigrationContext
-) => SavedObjectUnsanitizedDoc;
+) => SavedObjectUnsanitizedDoc;
/**
* Migration context provided when invoking a {@link SavedObjectMigrationFn | migration handler}
diff --git a/src/core/server/saved_objects/saved_objects_service.mock.ts b/src/core/server/saved_objects/saved_objects_service.mock.ts
index 7ba4613c857d7..4e1f5981d6a41 100644
--- a/src/core/server/saved_objects/saved_objects_service.mock.ts
+++ b/src/core/server/saved_objects/saved_objects_service.mock.ts
@@ -31,6 +31,7 @@ import { savedObjectsClientProviderMock } from './service/lib/scoped_client_prov
import { savedObjectsRepositoryMock } from './service/lib/repository.mock';
import { savedObjectsClientMock } from './service/saved_objects_client.mock';
import { typeRegistryMock } from './saved_objects_type_registry.mock';
+import { migrationMocks } from './migrations/mocks';
import { ServiceStatusLevels } from '../status';
type SavedObjectsServiceContract = PublicMethodsOf;
@@ -105,4 +106,5 @@ export const savedObjectsServiceMock = {
createSetupContract: createSetupContractMock,
createInternalStartContract: createInternalStartContractMock,
createStartContract: createStartContractMock,
+ createMigrationContext: migrationMocks.createContext,
};
diff --git a/src/core/server/saved_objects/serialization/types.ts b/src/core/server/saved_objects/serialization/types.ts
index a33e16895078e..acd2c7b5284aa 100644
--- a/src/core/server/saved_objects/serialization/types.ts
+++ b/src/core/server/saved_objects/serialization/types.ts
@@ -47,8 +47,8 @@ export interface SavedObjectsRawDocSource {
/**
* Saved Object base document
*/
-interface SavedObjectDoc {
- attributes: any;
+interface SavedObjectDoc {
+ attributes: T;
id?: string; // NOTE: SavedObjectDoc is used for uncreated objects where `id` is optional
type: string;
namespace?: string;
@@ -69,7 +69,7 @@ interface Referencable {
*
* @public
*/
-export type SavedObjectUnsanitizedDoc = SavedObjectDoc & Partial;
+export type SavedObjectUnsanitizedDoc = SavedObjectDoc & Partial;
/**
* Describes Saved Object documents that have passed through the migration
@@ -77,4 +77,4 @@ export type SavedObjectUnsanitizedDoc = SavedObjectDoc & Partial;
*
* @public
*/
-export type SavedObjectSanitizedDoc = SavedObjectDoc & Referencable;
+export type SavedObjectSanitizedDoc = SavedObjectDoc & Referencable;
diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md
index dc1c9d379d508..e8b77a8570291 100644
--- a/src/core/server/server.api.md
+++ b/src/core/server/server.api.md
@@ -1680,7 +1680,7 @@ export interface SavedObjectMigrationContext {
}
// @public
-export type SavedObjectMigrationFn = (doc: SavedObjectUnsanitizedDoc, context: SavedObjectMigrationContext) => SavedObjectUnsanitizedDoc;
+export type SavedObjectMigrationFn = (doc: SavedObjectUnsanitizedDoc, context: SavedObjectMigrationContext) => SavedObjectUnsanitizedDoc;
// @public
export interface SavedObjectMigrationMap {
@@ -1708,7 +1708,7 @@ export interface SavedObjectsAddToNamespacesOptions extends SavedObjectsBaseOpti
// Warning: (ae-forgotten-export) The symbol "Referencable" needs to be exported by the entry point index.d.ts
//
// @public
-export type SavedObjectSanitizedDoc = SavedObjectDoc & Referencable;
+export type SavedObjectSanitizedDoc = SavedObjectDoc & Referencable;
// @public (undocumented)
export interface SavedObjectsBaseOptions {
@@ -2311,7 +2311,7 @@ export class SavedObjectTypeRegistry {
}
// @public
-export type SavedObjectUnsanitizedDoc = SavedObjectDoc & Partial;
+export type SavedObjectUnsanitizedDoc = SavedObjectDoc & Partial;
// @public
export type ScopeableRequest = KibanaRequest | LegacyRequest | FakeRequest;
diff --git a/src/dev/precommit_hook/casing_check_config.js b/src/dev/precommit_hook/casing_check_config.js
index 66296736b3ad0..8630221b3e94f 100644
--- a/src/dev/precommit_hook/casing_check_config.js
+++ b/src/dev/precommit_hook/casing_check_config.js
@@ -35,9 +35,9 @@ export const IGNORE_FILE_GLOBS = [
'**/Gruntfile.js',
'tasks/config/**/*',
'**/{Dockerfile,docker-compose.yml}',
- 'x-pack/legacy/plugins/apm/**/*',
'x-pack/legacy/plugins/canvas/tasks/**/*',
'x-pack/legacy/plugins/canvas/canvas_plugin_src/**/*',
+ 'x-pack/plugins/monitoring/public/lib/jquery_flot/**/*',
'**/.*',
'**/{webpackShims,__mocks__}/**/*',
'x-pack/docs/**/*',
@@ -58,6 +58,11 @@ export const IGNORE_FILE_GLOBS = [
// filename required by api-extractor
'api-documenter.json',
+
+ // TODO fix file names in APM to remove these
+ 'x-pack/plugins/apm/public/**/*',
+ 'x-pack/plugins/apm/scripts/**/*',
+ 'x-pack/plugins/apm/e2e/**/*',
];
/**
@@ -160,12 +165,11 @@ export const TEMPORARILY_IGNORED_PATHS = [
'webpackShims/ui-bootstrap.js',
'x-pack/legacy/plugins/index_management/public/lib/editSettings.js',
'x-pack/legacy/plugins/license_management/public/store/reducers/licenseManagement.js',
- 'x-pack/legacy/plugins/monitoring/public/components/sparkline/__mocks__/plugins/xpack_main/jquery_flot.js',
- 'x-pack/legacy/plugins/monitoring/public/icons/alert-blue.svg',
- 'x-pack/legacy/plugins/monitoring/public/icons/health-gray.svg',
- 'x-pack/legacy/plugins/monitoring/public/icons/health-green.svg',
- 'x-pack/legacy/plugins/monitoring/public/icons/health-red.svg',
- 'x-pack/legacy/plugins/monitoring/public/icons/health-yellow.svg',
+ 'x-pack/plugins/monitoring/public/components/sparkline/__mocks__/plugins/xpack_main/jquery_flot.js',
+ 'x-pack/plugins/monitoring/public/icons/health-gray.svg',
+ 'x-pack/plugins/monitoring/public/icons/health-green.svg',
+ 'x-pack/plugins/monitoring/public/icons/health-red.svg',
+ 'x-pack/plugins/monitoring/public/icons/health-yellow.svg',
'x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/lib/pdf/assets/fonts/noto/NotoSansCJKtc-Medium.ttf',
'x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/lib/pdf/assets/fonts/noto/NotoSansCJKtc-Regular.ttf',
'x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/lib/pdf/assets/fonts/roboto/Roboto-Italic.ttf',
diff --git a/src/dev/run_check_lockfile_symlinks.js b/src/dev/run_check_lockfile_symlinks.js
index 6c6fc54638ee8..b912ea9ddb87e 100644
--- a/src/dev/run_check_lockfile_symlinks.js
+++ b/src/dev/run_check_lockfile_symlinks.js
@@ -35,9 +35,9 @@ const IGNORE_FILE_GLOBS = [
// fixtures aren't used in production, ignore them
'**/*fixtures*/**/*',
// cypress isn't used in production, ignore it
- 'x-pack/legacy/plugins/apm/e2e/*',
+ 'x-pack/plugins/apm/e2e/*',
// apm scripts aren't used in production, ignore them
- 'x-pack/legacy/plugins/apm/scripts/*',
+ 'x-pack/plugins/apm/scripts/*',
];
run(async ({ log }) => {
diff --git a/src/dev/storybook/aliases.ts b/src/dev/storybook/aliases.ts
index 43114b2edccfc..4dc930dae3e25 100644
--- a/src/dev/storybook/aliases.ts
+++ b/src/dev/storybook/aliases.ts
@@ -18,7 +18,7 @@
*/
export const storybookAliases = {
- apm: 'x-pack/legacy/plugins/apm/scripts/storybook.js',
+ apm: 'x-pack/plugins/apm/scripts/storybook.js',
canvas: 'x-pack/legacy/plugins/canvas/scripts/storybook_new.js',
codeeditor: 'src/plugins/kibana_react/public/code_editor/scripts/storybook.ts',
drilldowns: 'x-pack/plugins/drilldowns/scripts/storybook.js',
diff --git a/src/dev/typescript/projects.ts b/src/dev/typescript/projects.ts
index 01d8a30b598c1..a13f61af60173 100644
--- a/src/dev/typescript/projects.ts
+++ b/src/dev/typescript/projects.ts
@@ -30,7 +30,7 @@ export const PROJECTS = [
new Project(resolve(REPO_ROOT, 'x-pack/plugins/siem/cypress/tsconfig.json'), {
name: 'siem/cypress',
}),
- new Project(resolve(REPO_ROOT, 'x-pack/legacy/plugins/apm/e2e/tsconfig.json'), {
+ new Project(resolve(REPO_ROOT, 'x-pack/plugins/apm/e2e/tsconfig.json'), {
name: 'apm/cypress',
disableTypeCheck: true,
}),
diff --git a/src/legacy/server/config/config.js b/src/legacy/server/config/config.js
index c31ded608dd31..b186071edeaf7 100644
--- a/src/legacy/server/config/config.js
+++ b/src/legacy/server/config/config.js
@@ -19,7 +19,7 @@
import Joi from 'joi';
import _ from 'lodash';
-import override from './override';
+import { override } from './override';
import createDefaultSchema from './schema';
import { unset, deepCloneWithBuffers as clone, IS_KIBANA_DISTRIBUTABLE } from '../../utils';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
diff --git a/src/legacy/server/config/explode_by.test.js b/src/legacy/server/config/explode_by.test.js
deleted file mode 100644
index 741edba27d325..0000000000000
--- a/src/legacy/server/config/explode_by.test.js
+++ /dev/null
@@ -1,48 +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 explodeBy from './explode_by';
-
-describe('explode_by(dot, flatObject)', function() {
- it('should explode a flatten object with dots', function() {
- const flatObject = {
- 'test.enable': true,
- 'test.hosts': ['host-01', 'host-02'],
- };
- expect(explodeBy('.', flatObject)).toEqual({
- test: {
- enable: true,
- hosts: ['host-01', 'host-02'],
- },
- });
- });
-
- it('should explode a flatten object with slashes', function() {
- const flatObject = {
- 'test/enable': true,
- 'test/hosts': ['host-01', 'host-02'],
- };
- expect(explodeBy('/', flatObject)).toEqual({
- test: {
- enable: true,
- hosts: ['host-01', 'host-02'],
- },
- });
- });
-});
diff --git a/src/legacy/server/config/override.test.js b/src/legacy/server/config/override.test.js
deleted file mode 100644
index 331c586e28a87..0000000000000
--- a/src/legacy/server/config/override.test.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import override from './override';
-
-describe('override(target, source)', function() {
- it('should override the values form source to target', function() {
- const target = {
- test: {
- enable: true,
- host: ['host-01', 'host-02'],
- client: {
- type: 'sql',
- },
- },
- };
- const source = { test: { client: { type: 'nosql' } } };
- expect(override(target, source)).toEqual({
- test: {
- enable: true,
- host: ['host-01', 'host-02'],
- client: {
- type: 'nosql',
- },
- },
- });
- });
-});
diff --git a/src/legacy/server/config/override.test.ts b/src/legacy/server/config/override.test.ts
new file mode 100644
index 0000000000000..4e21a88e79e61
--- /dev/null
+++ b/src/legacy/server/config/override.test.ts
@@ -0,0 +1,130 @@
+/*
+ * 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 { override } from './override';
+
+describe('override(target, source)', function() {
+ it('should override the values form source to target', function() {
+ const target = {
+ test: {
+ enable: true,
+ host: ['something else'],
+ client: {
+ type: 'sql',
+ },
+ },
+ };
+
+ const source = {
+ test: {
+ host: ['host-01', 'host-02'],
+ client: {
+ type: 'nosql',
+ },
+ foo: {
+ bar: {
+ baz: 1,
+ },
+ },
+ },
+ };
+
+ expect(override(target, source)).toMatchInlineSnapshot(`
+ Object {
+ "test": Object {
+ "client": Object {
+ "type": "nosql",
+ },
+ "enable": true,
+ "foo": Object {
+ "bar": Object {
+ "baz": 1,
+ },
+ },
+ "host": Array [
+ "host-01",
+ "host-02",
+ ],
+ },
+ }
+ `);
+ });
+
+ it('does not mutate arguments', () => {
+ const target = {
+ foo: {
+ bar: 1,
+ baz: 1,
+ },
+ };
+
+ const source = {
+ foo: {
+ bar: 2,
+ },
+ box: 2,
+ };
+
+ expect(override(target, source)).toMatchInlineSnapshot(`
+ Object {
+ "box": 2,
+ "foo": Object {
+ "bar": 2,
+ "baz": 1,
+ },
+ }
+ `);
+ expect(target).not.toHaveProperty('box');
+ expect(source.foo).not.toHaveProperty('baz');
+ });
+
+ it('explodes keys with dots in them', () => {
+ const target = {
+ foo: {
+ bar: 1,
+ },
+ 'baz.box.boot.bar.bar': 20,
+ };
+
+ const source = {
+ 'foo.bar': 2,
+ 'baz.box.boot': {
+ 'bar.foo': 10,
+ },
+ };
+
+ expect(override(target, source)).toMatchInlineSnapshot(`
+ Object {
+ "baz": Object {
+ "box": Object {
+ "boot": Object {
+ "bar": Object {
+ "bar": 20,
+ "foo": 10,
+ },
+ },
+ },
+ },
+ "foo": Object {
+ "bar": 2,
+ },
+ }
+ `);
+ });
+});
diff --git a/src/legacy/server/config/override.ts b/src/legacy/server/config/override.ts
new file mode 100644
index 0000000000000..3dd7d62016004
--- /dev/null
+++ b/src/legacy/server/config/override.ts
@@ -0,0 +1,52 @@
+/*
+ * 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 isObject = (v: any): v is Record =>
+ typeof v === 'object' && v !== null && !Array.isArray(v);
+
+const assignDeep = (target: Record, source: Record) => {
+ for (let [key, value] of Object.entries(source)) {
+ // unwrap dot-separated keys
+ if (key.includes('.')) {
+ const [first, ...others] = key.split('.');
+ key = first;
+ value = { [others.join('.')]: value };
+ }
+
+ if (isObject(value)) {
+ if (!target.hasOwnProperty(key)) {
+ target[key] = {};
+ }
+
+ assignDeep(target[key], value);
+ } else {
+ target[key] = value;
+ }
+ }
+};
+
+export const override = (...sources: Array>): Record => {
+ const result = {};
+
+ for (const object of sources) {
+ assignDeep(result, object);
+ }
+
+ return result;
+};
diff --git a/src/legacy/ui/public/new_platform/new_platform.karma_mock.js b/src/legacy/ui/public/new_platform/new_platform.karma_mock.js
index 271586bb8c582..3caba24748bfa 100644
--- a/src/legacy/ui/public/new_platform/new_platform.karma_mock.js
+++ b/src/legacy/ui/public/new_platform/new_platform.karma_mock.js
@@ -462,16 +462,6 @@ export const npStart = {
types: aggTypesRegistry.start(),
},
__LEGACY: {
- AggConfig: sinon.fake(),
- AggType: sinon.fake(),
- aggTypeFieldFilters: {
- addFilter: sinon.fake(),
- filter: sinon.fake(),
- },
- FieldParamType: sinon.fake(),
- MetricAggType: sinon.fake(),
- parentPipelineAggHelper: sinon.fake(),
- siblingPipelineAggHelper: sinon.fake(),
esClient: {
search: sinon.fake(),
msearch: sinon.fake(),
diff --git a/src/plugins/dashboard/public/plugin.tsx b/src/plugins/dashboard/public/plugin.tsx
index 5f6b67ee6ad20..7de054f2eaa9c 100644
--- a/src/plugins/dashboard/public/plugin.tsx
+++ b/src/plugins/dashboard/public/plugin.tsx
@@ -141,10 +141,14 @@ export class DashboardPlugin
if (share) {
share.urlGenerators.registerUrlGenerator(
- createDirectAccessDashboardLinkGenerator(async () => ({
- appBasePath: (await startServices)[0].application.getUrlForApp('dashboard'),
- useHashedUrl: (await startServices)[0].uiSettings.get('state:storeInSessionStorage'),
- }))
+ createDirectAccessDashboardLinkGenerator(async () => {
+ const [coreStart, , selfStart] = await startServices;
+ return {
+ appBasePath: coreStart.application.getUrlForApp('dashboard'),
+ useHashedUrl: coreStart.uiSettings.get('state:storeInSessionStorage'),
+ savedDashboardLoader: selfStart.getSavedDashboardLoader(),
+ };
+ })
);
}
diff --git a/src/plugins/dashboard/public/url_generator.test.ts b/src/plugins/dashboard/public/url_generator.test.ts
index d48aacc1d8c1e..248a3f991d6cb 100644
--- a/src/plugins/dashboard/public/url_generator.test.ts
+++ b/src/plugins/dashboard/public/url_generator.test.ts
@@ -21,10 +21,33 @@ import { createDirectAccessDashboardLinkGenerator } from './url_generator';
import { hashedItemStore } from '../../kibana_utils/public';
// eslint-disable-next-line
import { mockStorage } from '../../kibana_utils/public/storage/hashed_item_store/mock';
-import { esFilters } from '../../data/public';
+import { esFilters, Filter } from '../../data/public';
+import { SavedObjectLoader } from '../../saved_objects/public';
const APP_BASE_PATH: string = 'xyz/app/kibana';
+const createMockDashboardLoader = (
+ dashboardToFilters: {
+ [dashboardId: string]: () => Filter[];
+ } = {}
+) => {
+ return {
+ get: async (dashboardId: string) => {
+ return {
+ searchSource: {
+ getField: (field: string) => {
+ if (field === 'filter')
+ return dashboardToFilters[dashboardId] ? dashboardToFilters[dashboardId]() : [];
+ throw new Error(
+ `createMockDashboardLoader > searchSource > getField > ${field} is not mocked`
+ );
+ },
+ },
+ };
+ },
+ } as SavedObjectLoader;
+};
+
describe('dashboard url generator', () => {
beforeEach(() => {
// @ts-ignore
@@ -33,7 +56,11 @@ describe('dashboard url generator', () => {
test('creates a link to a saved dashboard', async () => {
const generator = createDirectAccessDashboardLinkGenerator(() =>
- Promise.resolve({ appBasePath: APP_BASE_PATH, useHashedUrl: false })
+ Promise.resolve({
+ appBasePath: APP_BASE_PATH,
+ useHashedUrl: false,
+ savedDashboardLoader: createMockDashboardLoader(),
+ })
);
const url = await generator.createUrl!({});
expect(url).toMatchInlineSnapshot(`"xyz/app/kibana#/dashboard?_a=()&_g=()"`);
@@ -41,7 +68,11 @@ describe('dashboard url generator', () => {
test('creates a link with global time range set up', async () => {
const generator = createDirectAccessDashboardLinkGenerator(() =>
- Promise.resolve({ appBasePath: APP_BASE_PATH, useHashedUrl: false })
+ Promise.resolve({
+ appBasePath: APP_BASE_PATH,
+ useHashedUrl: false,
+ savedDashboardLoader: createMockDashboardLoader(),
+ })
);
const url = await generator.createUrl!({
timeRange: { to: 'now', from: 'now-15m', mode: 'relative' },
@@ -53,7 +84,11 @@ describe('dashboard url generator', () => {
test('creates a link with filters, time range, refresh interval and query to a saved object', async () => {
const generator = createDirectAccessDashboardLinkGenerator(() =>
- Promise.resolve({ appBasePath: APP_BASE_PATH, useHashedUrl: false })
+ Promise.resolve({
+ appBasePath: APP_BASE_PATH,
+ useHashedUrl: false,
+ savedDashboardLoader: createMockDashboardLoader(),
+ })
);
const url = await generator.createUrl!({
timeRange: { to: 'now', from: 'now-15m', mode: 'relative' },
@@ -89,7 +124,11 @@ describe('dashboard url generator', () => {
test('if no useHash setting is given, uses the one was start services', async () => {
const generator = createDirectAccessDashboardLinkGenerator(() =>
- Promise.resolve({ appBasePath: APP_BASE_PATH, useHashedUrl: true })
+ Promise.resolve({
+ appBasePath: APP_BASE_PATH,
+ useHashedUrl: true,
+ savedDashboardLoader: createMockDashboardLoader(),
+ })
);
const url = await generator.createUrl!({
timeRange: { to: 'now', from: 'now-15m', mode: 'relative' },
@@ -99,7 +138,11 @@ describe('dashboard url generator', () => {
test('can override a false useHash ui setting', async () => {
const generator = createDirectAccessDashboardLinkGenerator(() =>
- Promise.resolve({ appBasePath: APP_BASE_PATH, useHashedUrl: false })
+ Promise.resolve({
+ appBasePath: APP_BASE_PATH,
+ useHashedUrl: false,
+ savedDashboardLoader: createMockDashboardLoader(),
+ })
);
const url = await generator.createUrl!({
timeRange: { to: 'now', from: 'now-15m', mode: 'relative' },
@@ -110,7 +153,11 @@ describe('dashboard url generator', () => {
test('can override a true useHash ui setting', async () => {
const generator = createDirectAccessDashboardLinkGenerator(() =>
- Promise.resolve({ appBasePath: APP_BASE_PATH, useHashedUrl: true })
+ Promise.resolve({
+ appBasePath: APP_BASE_PATH,
+ useHashedUrl: true,
+ savedDashboardLoader: createMockDashboardLoader(),
+ })
);
const url = await generator.createUrl!({
timeRange: { to: 'now', from: 'now-15m', mode: 'relative' },
@@ -118,4 +165,150 @@ describe('dashboard url generator', () => {
});
expect(url.indexOf('relative')).toBeGreaterThan(1);
});
+
+ describe('preserving saved filters', () => {
+ const savedFilter1 = {
+ meta: {
+ alias: null,
+ disabled: false,
+ negate: false,
+ },
+ query: { query: 'savedfilter1' },
+ };
+
+ const savedFilter2 = {
+ meta: {
+ alias: null,
+ disabled: false,
+ negate: false,
+ },
+ query: { query: 'savedfilter2' },
+ };
+
+ const appliedFilter = {
+ meta: {
+ alias: null,
+ disabled: false,
+ negate: false,
+ },
+ query: { query: 'appliedfilter' },
+ };
+
+ test('attaches filters from destination dashboard', async () => {
+ const generator = createDirectAccessDashboardLinkGenerator(() =>
+ Promise.resolve({
+ appBasePath: APP_BASE_PATH,
+ useHashedUrl: false,
+ savedDashboardLoader: createMockDashboardLoader({
+ ['dashboard1']: () => [savedFilter1],
+ ['dashboard2']: () => [savedFilter2],
+ }),
+ })
+ );
+
+ const urlToDashboard1 = await generator.createUrl!({
+ dashboardId: 'dashboard1',
+ filters: [appliedFilter],
+ });
+
+ expect(urlToDashboard1).toEqual(expect.stringContaining('query:savedfilter1'));
+ expect(urlToDashboard1).toEqual(expect.stringContaining('query:appliedfilter'));
+
+ const urlToDashboard2 = await generator.createUrl!({
+ dashboardId: 'dashboard2',
+ filters: [appliedFilter],
+ });
+
+ expect(urlToDashboard2).toEqual(expect.stringContaining('query:savedfilter2'));
+ expect(urlToDashboard2).toEqual(expect.stringContaining('query:appliedfilter'));
+ });
+
+ test("doesn't fail if can't retrieve filters from destination dashboard", async () => {
+ const generator = createDirectAccessDashboardLinkGenerator(() =>
+ Promise.resolve({
+ appBasePath: APP_BASE_PATH,
+ useHashedUrl: false,
+ savedDashboardLoader: createMockDashboardLoader({
+ ['dashboard1']: () => {
+ throw new Error('Not found');
+ },
+ }),
+ })
+ );
+
+ const url = await generator.createUrl!({
+ dashboardId: 'dashboard1',
+ filters: [appliedFilter],
+ });
+
+ expect(url).not.toEqual(expect.stringContaining('query:savedfilter1'));
+ expect(url).toEqual(expect.stringContaining('query:appliedfilter'));
+ });
+
+ test('can enforce empty filters', async () => {
+ const generator = createDirectAccessDashboardLinkGenerator(() =>
+ Promise.resolve({
+ appBasePath: APP_BASE_PATH,
+ useHashedUrl: false,
+ savedDashboardLoader: createMockDashboardLoader({
+ ['dashboard1']: () => [savedFilter1],
+ }),
+ })
+ );
+
+ const url = await generator.createUrl!({
+ dashboardId: 'dashboard1',
+ filters: [],
+ preserveSavedFilters: false,
+ });
+
+ expect(url).not.toEqual(expect.stringContaining('query:savedfilter1'));
+ expect(url).not.toEqual(expect.stringContaining('query:appliedfilter'));
+ expect(url).toMatchInlineSnapshot(
+ `"xyz/app/kibana#/dashboard/dashboard1?_a=(filters:!())&_g=(filters:!())"`
+ );
+ });
+
+ test('no filters in result url if no filters applied', async () => {
+ const generator = createDirectAccessDashboardLinkGenerator(() =>
+ Promise.resolve({
+ appBasePath: APP_BASE_PATH,
+ useHashedUrl: false,
+ savedDashboardLoader: createMockDashboardLoader({
+ ['dashboard1']: () => [savedFilter1],
+ }),
+ })
+ );
+
+ const url = await generator.createUrl!({
+ dashboardId: 'dashboard1',
+ });
+ expect(url).not.toEqual(expect.stringContaining('filters'));
+ expect(url).toMatchInlineSnapshot(`"xyz/app/kibana#/dashboard/dashboard1?_a=()&_g=()"`);
+ });
+
+ test('can turn off preserving filters', async () => {
+ const generator = createDirectAccessDashboardLinkGenerator(() =>
+ Promise.resolve({
+ appBasePath: APP_BASE_PATH,
+ useHashedUrl: false,
+ savedDashboardLoader: createMockDashboardLoader({
+ ['dashboard1']: () => [savedFilter1],
+ }),
+ })
+ );
+ const urlWithPreservedFiltersTurnedOff = await generator.createUrl!({
+ dashboardId: 'dashboard1',
+ filters: [appliedFilter],
+ preserveSavedFilters: false,
+ });
+
+ expect(urlWithPreservedFiltersTurnedOff).not.toEqual(
+ expect.stringContaining('query:savedfilter1')
+ );
+ expect(urlWithPreservedFiltersTurnedOff).toEqual(
+ expect.stringContaining('query:appliedfilter')
+ );
+ });
+ });
});
diff --git a/src/plugins/dashboard/public/url_generator.ts b/src/plugins/dashboard/public/url_generator.ts
index 0fdf395e75bca..6f121ceb2d373 100644
--- a/src/plugins/dashboard/public/url_generator.ts
+++ b/src/plugins/dashboard/public/url_generator.ts
@@ -27,6 +27,7 @@ import {
} from '../../data/public';
import { setStateToKbnUrl } from '../../kibana_utils/public';
import { UrlGeneratorsDefinition, UrlGeneratorState } from '../../share/public';
+import { SavedObjectLoader } from '../../saved_objects/public';
export const STATE_STORAGE_KEY = '_a';
export const GLOBAL_STATE_STORAGE_KEY = '_g';
@@ -64,10 +65,22 @@ export type DashboardAppLinkGeneratorState = UrlGeneratorState<{
* whether to hash the data in the url to avoid url length issues.
*/
useHash?: boolean;
+
+ /**
+ * When `true` filters from saved filters from destination dashboard as merged with applied filters
+ * When `false` applied filters take precedence and override saved filters
+ *
+ * true is default
+ */
+ preserveSavedFilters?: boolean;
}>;
export const createDirectAccessDashboardLinkGenerator = (
- getStartServices: () => Promise<{ appBasePath: string; useHashedUrl: boolean }>
+ getStartServices: () => Promise<{
+ appBasePath: string;
+ useHashedUrl: boolean;
+ savedDashboardLoader: SavedObjectLoader;
+ }>
): UrlGeneratorsDefinition => ({
id: DASHBOARD_APP_URL_GENERATOR,
createUrl: async state => {
@@ -76,6 +89,19 @@ export const createDirectAccessDashboardLinkGenerator = (
const appBasePath = startServices.appBasePath;
const hash = state.dashboardId ? `dashboard/${state.dashboardId}` : `dashboard`;
+ const getSavedFiltersFromDestinationDashboardIfNeeded = async (): Promise => {
+ if (state.preserveSavedFilters === false) return [];
+ if (!state.dashboardId) return [];
+ try {
+ const dashboard = await startServices.savedDashboardLoader.get(state.dashboardId);
+ return dashboard?.searchSource?.getField('filter') ?? [];
+ } catch (e) {
+ // in case dashboard is missing, built the url without those filters
+ // dashboard app will handle redirect to landing page with toast message
+ return [];
+ }
+ };
+
const cleanEmptyKeys = (stateObj: Record) => {
Object.keys(stateObj).forEach(key => {
if (stateObj[key] === undefined) {
@@ -85,11 +111,18 @@ export const createDirectAccessDashboardLinkGenerator = (
return stateObj;
};
+ // leave filters `undefined` if no filters was applied
+ // in this case dashboard will restore saved filters on its own
+ const filters = state.filters && [
+ ...(await getSavedFiltersFromDestinationDashboardIfNeeded()),
+ ...state.filters,
+ ];
+
const appStateUrl = setStateToKbnUrl(
STATE_STORAGE_KEY,
cleanEmptyKeys({
query: state.query,
- filters: state.filters?.filter(f => !esFilters.isFilterPinned(f)),
+ filters: filters?.filter(f => !esFilters.isFilterPinned(f)),
}),
{ useHash },
`${appBasePath}#/${hash}`
@@ -99,7 +132,7 @@ export const createDirectAccessDashboardLinkGenerator = (
GLOBAL_STATE_STORAGE_KEY,
cleanEmptyKeys({
time: state.timeRange,
- filters: state.filters?.filter(f => esFilters.isFilterPinned(f)),
+ filters: filters?.filter(f => esFilters.isFilterPinned(f)),
refreshInterval: state.refreshInterval,
}),
{ useHash },
diff --git a/src/plugins/dashboard/server/saved_objects/dashboard_migrations.test.ts b/src/plugins/dashboard/server/saved_objects/dashboard_migrations.test.ts
index 9829498118cc0..22ed18f75c652 100644
--- a/src/plugins/dashboard/server/saved_objects/dashboard_migrations.test.ts
+++ b/src/plugins/dashboard/server/saved_objects/dashboard_migrations.test.ts
@@ -18,14 +18,17 @@
*/
import { SavedObjectUnsanitizedDoc } from 'kibana/server';
+import { savedObjectsServiceMock } from '../../../../core/server/mocks';
import { dashboardSavedObjectTypeMigrations as migrations } from './dashboard_migrations';
+const contextMock = savedObjectsServiceMock.createMigrationContext();
+
describe('dashboard', () => {
describe('7.0.0', () => {
const migration = migrations['7.0.0'];
test('skips error on empty object', () => {
- expect(migration({} as SavedObjectUnsanitizedDoc)).toMatchInlineSnapshot(`
+ expect(migration({} as SavedObjectUnsanitizedDoc, contextMock)).toMatchInlineSnapshot(`
Object {
"references": Array [],
}
@@ -44,7 +47,7 @@ Object {
'[{"id":"1","type":"visualization","foo":true},{"id":"2","type":"visualization","bar":true}]',
},
};
- const migratedDoc = migration(doc);
+ const migratedDoc = migration(doc, contextMock);
expect(migratedDoc).toMatchInlineSnapshot(`
Object {
"attributes": Object {
@@ -83,7 +86,7 @@ Object {
'[{"id":"1","type":"visualization","foo":true},{"id":"2","type":"visualization","bar":true}]',
},
};
- const migratedDoc = migration(doc);
+ const migratedDoc = migration(doc, contextMock);
expect(migratedDoc).toMatchInlineSnapshot(`
Object {
"attributes": Object {
@@ -122,7 +125,7 @@ Object {
'[{"id":"1","type":"visualization","foo":true},{"id":"2","type":"visualization","bar":true}]',
},
};
- expect(migration(doc)).toMatchInlineSnapshot(`
+ expect(migration(doc, contextMock)).toMatchInlineSnapshot(`
Object {
"attributes": Object {
"kibanaSavedObjectMeta": Object {
@@ -160,7 +163,7 @@ Object {
'[{"id":"1","type":"visualization","foo":true},{"id":"2","type":"visualization","bar":true}]',
},
};
- expect(migration(doc)).toMatchInlineSnapshot(`
+ expect(migration(doc, contextMock)).toMatchInlineSnapshot(`
Object {
"attributes": Object {
"kibanaSavedObjectMeta": Object {
@@ -198,7 +201,7 @@ Object {
'[{"id":"1","type":"visualization","foo":true},{"id":"2","type":"visualization","bar":true}]',
},
};
- const migratedDoc = migration(doc);
+ const migratedDoc = migration(doc, contextMock);
expect(migratedDoc).toMatchInlineSnapshot(`
Object {
"attributes": Object {
@@ -237,7 +240,7 @@ Object {
'[{"id":"1","type":"visualization","foo":true},{"id":"2","type":"visualization","bar":true}]',
},
};
- const migratedDoc = migration(doc);
+ const migratedDoc = migration(doc, contextMock);
expect(migratedDoc).toMatchInlineSnapshot(`
Object {
"attributes": Object {
@@ -291,7 +294,7 @@ Object {
'[{"id":"1","type":"visualization","foo":true},{"id":"2","type":"visualization","bar":true}]',
},
};
- const migratedDoc = migration(doc);
+ const migratedDoc = migration(doc, contextMock);
expect(migratedDoc).toMatchInlineSnapshot(`
Object {
@@ -331,7 +334,7 @@ Object {
panelsJSON: 123,
},
} as SavedObjectUnsanitizedDoc;
- expect(migration(doc)).toMatchInlineSnapshot(`
+ expect(migration(doc, contextMock)).toMatchInlineSnapshot(`
Object {
"attributes": Object {
"panelsJSON": 123,
@@ -349,7 +352,7 @@ Object {
panelsJSON: '{123abc}',
},
} as SavedObjectUnsanitizedDoc;
- expect(migration(doc)).toMatchInlineSnapshot(`
+ expect(migration(doc, contextMock)).toMatchInlineSnapshot(`
Object {
"attributes": Object {
"panelsJSON": "{123abc}",
@@ -367,7 +370,7 @@ Object {
panelsJSON: '{}',
},
} as SavedObjectUnsanitizedDoc;
- expect(migration(doc)).toMatchInlineSnapshot(`
+ expect(migration(doc, contextMock)).toMatchInlineSnapshot(`
Object {
"attributes": Object {
"panelsJSON": "{}",
@@ -385,7 +388,7 @@ Object {
panelsJSON: '[{"id":"123"}]',
},
} as SavedObjectUnsanitizedDoc;
- expect(migration(doc)).toMatchInlineSnapshot(`
+ expect(migration(doc, contextMock)).toMatchInlineSnapshot(`
Object {
"attributes": Object {
"panelsJSON": "[{\\"id\\":\\"123\\"}]",
@@ -403,7 +406,7 @@ Object {
panelsJSON: '[{"type":"visualization"}]',
},
} as SavedObjectUnsanitizedDoc;
- expect(migration(doc)).toMatchInlineSnapshot(`
+ expect(migration(doc, contextMock)).toMatchInlineSnapshot(`
Object {
"attributes": Object {
"panelsJSON": "[{\\"type\\":\\"visualization\\"}]",
@@ -422,7 +425,7 @@ Object {
'[{"id":"1","type":"visualization","foo":true},{"id":"2","type":"visualization","bar":true}]',
},
} as SavedObjectUnsanitizedDoc;
- const migratedDoc = migration(doc);
+ const migratedDoc = migration(doc, contextMock);
expect(migratedDoc).toMatchInlineSnapshot(`
Object {
"attributes": Object {
diff --git a/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts b/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts
index 7c1d0568cd3d7..4f7945d6dd601 100644
--- a/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts
+++ b/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts
@@ -19,7 +19,7 @@
import { get, flow } from 'lodash';
-import { SavedObjectMigrationFn, SavedObjectUnsanitizedDoc } from 'kibana/server';
+import { SavedObjectMigrationFn } from 'kibana/server';
import { migrations730 } from './migrations_730';
import { migrateMatchAllQuery } from './migrate_match_all_query';
import { DashboardDoc700To720 } from '../../common';
@@ -62,7 +62,7 @@ function migrateIndexPattern(doc: DashboardDoc700To720) {
doc.attributes.kibanaSavedObjectMeta.searchSourceJSON = JSON.stringify(searchSource);
}
-const migrations700: SavedObjectMigrationFn = (doc): DashboardDoc700To720 => {
+const migrations700: SavedObjectMigrationFn = (doc): DashboardDoc700To720 => {
// Set new "references" attribute
doc.references = doc.references || [];
@@ -111,7 +111,7 @@ export const dashboardSavedObjectTypeMigrations = {
* in that version. So we apply this twice, once with 6.7.2 and once with 7.0.1 while the backport to 6.7
* only contained the 6.7.2 migration and not the 7.0.1 migration.
*/
- '6.7.2': flow(migrateMatchAllQuery),
- '7.0.0': flow<(doc: SavedObjectUnsanitizedDoc) => DashboardDoc700To720>(migrations700),
- '7.3.0': flow(migrations730),
+ '6.7.2': flow>(migrateMatchAllQuery),
+ '7.0.0': flow>(migrations700),
+ '7.3.0': flow>(migrations730),
};
diff --git a/src/plugins/dashboard/server/saved_objects/migrate_match_all_query.ts b/src/plugins/dashboard/server/saved_objects/migrate_match_all_query.ts
index 5b8582bf821ef..db2fbeb278802 100644
--- a/src/plugins/dashboard/server/saved_objects/migrate_match_all_query.ts
+++ b/src/plugins/dashboard/server/saved_objects/migrate_match_all_query.ts
@@ -21,7 +21,7 @@ import { SavedObjectMigrationFn } from 'kibana/server';
import { get } from 'lodash';
import { DEFAULT_QUERY_LANGUAGE } from '../../../data/common';
-export const migrateMatchAllQuery: SavedObjectMigrationFn = doc => {
+export const migrateMatchAllQuery: SavedObjectMigrationFn = doc => {
const searchSourceJSON = get(doc, 'attributes.kibanaSavedObjectMeta.searchSourceJSON');
if (searchSourceJSON) {
diff --git a/src/plugins/dashboard/server/saved_objects/migrations_730.test.ts b/src/plugins/dashboard/server/saved_objects/migrations_730.test.ts
index aa744324428a4..a58df547fa522 100644
--- a/src/plugins/dashboard/server/saved_objects/migrations_730.test.ts
+++ b/src/plugins/dashboard/server/saved_objects/migrations_730.test.ts
@@ -17,19 +17,13 @@
* under the License.
*/
+import { savedObjectsServiceMock } from '../../../../core/server/mocks';
import { dashboardSavedObjectTypeMigrations as migrations } from './dashboard_migrations';
import { migrations730 } from './migrations_730';
import { DashboardDoc700To720, DashboardDoc730ToLatest, DashboardDocPre700 } from '../../common';
import { RawSavedDashboardPanel730ToLatest } from '../../common';
-const mockContext = {
- log: {
- warning: () => {},
- warn: () => {},
- debug: () => {},
- info: () => {},
- },
-};
+const mockContext = savedObjectsServiceMock.createMigrationContext();
test('dashboard migration 7.3.0 migrates filters to query on search source', () => {
const doc: DashboardDoc700To720 = {
@@ -95,7 +89,7 @@ test('dashboard migration 7.3.0 migrates filters to query on search source when
},
};
- const doc700: DashboardDoc700To720 = migrations['7.0.0'](doc);
+ const doc700 = migrations['7.0.0'](doc, mockContext);
const newDoc = migrations['7.3.0'](doc700, mockContext);
const parsedSearchSource = JSON.parse(newDoc.attributes.kibanaSavedObjectMeta.searchSourceJSON);
@@ -127,7 +121,7 @@ test('dashboard migration works when panelsJSON is missing panelIndex', () => {
},
};
- const doc700: DashboardDoc700To720 = migrations['7.0.0'](doc);
+ const doc700 = migrations['7.0.0'](doc, mockContext);
const newDoc = migrations['7.3.0'](doc700, mockContext);
const parsedSearchSource = JSON.parse(newDoc.attributes.kibanaSavedObjectMeta.searchSourceJSON);
diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts
index 60d8079b22347..75deff23ce20d 100644
--- a/src/plugins/data/public/index.ts
+++ b/src/plugins/data/public/index.ts
@@ -288,13 +288,8 @@ export {
import {
// aggs
- AggConfigs,
- aggTypeFilters,
- aggGroupNamesMap,
CidrMask,
- convertDateRangeToString,
- convertIPRangeToString,
- intervalOptions, // only used in Discover
+ intervalOptions,
isDateHistogramBucketAggConfig,
isNumberType,
isStringType,
@@ -326,26 +321,22 @@ export { ParsedInterval } from '../common';
export {
// aggs
+ AggGroupLabels,
+ AggGroupName,
AggGroupNames,
- AggParam, // only the type is used externally, only in vis editor
- AggParamOption, // only the type is used externally
+ AggParam,
+ AggParamOption,
AggParamType,
- AggTypeFieldFilters, // TODO convert to interface
- AggTypeFilters, // TODO convert to interface
AggConfigOptions,
BUCKET_TYPES,
- DateRangeKey, // only used in field formatter deserialization, which will live in data
IAggConfig,
IAggConfigs,
- IAggGroupNames,
IAggType,
IFieldParamType,
IMetricAggType,
- IpRangeKey, // only used in field formatter deserialization, which will live in data
METRIC_TYPES,
- OptionedParamEditorProps, // only type is used externally
OptionedParamType,
- OptionedValueProp, // only type is used externally
+ OptionedValueProp,
// search
ES_SEARCH_STRATEGY,
SYNC_SEARCH_STRATEGY,
@@ -383,17 +374,12 @@ export {
// Search namespace
export const search = {
aggs: {
- AggConfigs,
- aggGroupNamesMap,
- aggTypeFilters,
CidrMask,
- convertDateRangeToString,
- convertIPRangeToString,
dateHistogramInterval,
- intervalOptions, // only used in Discover
+ intervalOptions,
InvalidEsCalendarIntervalError,
InvalidEsIntervalFormatError,
- isDateHistogramBucketAggConfig,
+ isDateHistogramBucketAggConfig, // TODO: remove in build_pipeline refactor
isNumberType,
isStringType,
isType,
diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md
index 91dea66f06a94..b0bb911dca9e5 100644
--- a/src/plugins/data/public/public.api.md
+++ b/src/plugins/data/public/public.api.md
@@ -26,7 +26,6 @@ import { History } from 'history';
import { HttpSetup } from 'src/core/public';
import { HttpStart } from 'src/core/public';
import { IconType } from '@elastic/eui';
-import { IndexPatternField as IndexPatternField_2 } from 'src/plugins/data/public';
import { InjectedIntl } from '@kbn/i18n/react';
import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
import { IUiSettingsClient } from 'src/core/public';
@@ -68,6 +67,20 @@ export type AggConfigOptions = Assign;
+// Warning: (ae-missing-release-tag) "AggGroupLabels" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export const AggGroupLabels: {
+ [AggGroupNames.Buckets]: string;
+ [AggGroupNames.Metrics]: string;
+ [AggGroupNames.None]: string;
+};
+
+// Warning: (ae-missing-release-tag) "AggGroupName" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export type AggGroupName = $Values;
+
// Warning: (ae-missing-release-tag) "AggGroupNames" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
@@ -108,32 +121,6 @@ export class AggParamType extends Ba
makeAgg: (agg: TAggConfig, state?: AggConfigSerialized) => TAggConfig;
}
-// Warning: (ae-missing-release-tag) "AggTypeFieldFilters" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "AggTypeFieldFilter"
-// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "AggType"
-//
-// @public
-export class AggTypeFieldFilters {
- // Warning: (ae-forgotten-export) The symbol "AggTypeFieldFilter" needs to be exported by the entry point index.d.ts
- // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "AggTypeFieldFilter"
- addFilter(filter: AggTypeFieldFilter): void;
- // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "any"
- filter(fields: IndexPatternField_2[], aggConfig: IAggConfig): IndexPatternField_2[];
- }
-
-// Warning: (ae-missing-release-tag) "AggTypeFilters" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "AggTypeFilter"
-// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "AggConfig"
-//
-// @public
-export class AggTypeFilters {
- // Warning: (ae-forgotten-export) The symbol "AggTypeFilter" needs to be exported by the entry point index.d.ts
- // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "AggTypeFilter"
- addFilter(filter: AggTypeFilter): void;
- // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "AggType"
- filter(aggTypes: IAggType[], indexPattern: IndexPattern, aggConfig: IAggConfig, aggFilter: string[]): IAggType[];
- }
-
// Warning: (ae-forgotten-export) The symbol "DateFormat" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "baseFormattersPublic" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
@@ -266,16 +253,6 @@ export interface DataPublicPluginStart {
};
}
-// Warning: (ae-missing-release-tag) "DateRangeKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
-export interface DateRangeKey {
- // (undocumented)
- from: number;
- // (undocumented)
- to: number;
-}
-
// @public (undocumented)
export enum ES_FIELD_TYPES {
// (undocumented)
@@ -714,11 +691,6 @@ export type IAggConfig = AggConfig;
// @internal
export type IAggConfigs = AggConfigs;
-// Warning: (ae-missing-release-tag) "IAggGroupNames" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
-export type IAggGroupNames = $Values;
-
// Warning: (ae-forgotten-export) The symbol "AggType" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "IAggType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
@@ -1101,18 +1073,6 @@ export type InputTimeRange = TimeRange | {
to: Moment;
};
-// Warning: (ae-missing-release-tag) "IpRangeKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
-export type IpRangeKey = {
- type: 'mask';
- mask: string;
-} | {
- type: 'range';
- from: string;
- to: string;
-};
-
// Warning: (ae-missing-release-tag) "IRequestTypesMap" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
@@ -1290,16 +1250,6 @@ export enum METRIC_TYPES {
TOP_HITS = "top_hits"
}
-// Warning: (ae-missing-release-tag) "OptionedParamEditorProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
-export interface OptionedParamEditorProps {
- // (undocumented)
- aggParam: {
- options: T[];
- };
-}
-
// Warning: (ae-missing-release-tag) "OptionedParamType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
@@ -1578,12 +1528,7 @@ export type SavedQueryTimeFilter = TimeRange & {
// @public (undocumented)
export const search: {
aggs: {
- AggConfigs: typeof AggConfigs;
- aggGroupNamesMap: () => Record<"metrics" | "buckets", string>;
- aggTypeFilters: import("./search/aggs/filter/agg_type_filters").AggTypeFilters;
CidrMask: typeof CidrMask;
- convertDateRangeToString: typeof convertDateRangeToString;
- convertIPRangeToString: (range: import("./search").IpRangeKey, format: (val: any) => string) => string;
dateHistogramInterval: typeof dateHistogramInterval;
intervalOptions: ({
display: string;
@@ -1870,21 +1815,20 @@ export type TSearchStrategyProvider = (context: ISearc
// src/plugins/data/public/index.ts:236:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:236:27 - (ae-forgotten-export) The symbol "getRoutes" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:236:27 - (ae-forgotten-export) The symbol "formatHitProvider" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:384:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:384:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:384:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:384:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:389:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:390:1 - (ae-forgotten-export) The symbol "convertDateRangeToString" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:392:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:401:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:402:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:403:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:407:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:408:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:411:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:412:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
-// src/plugins/data/public/index.ts:415:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:375:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:375:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:375:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:375:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:377:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:378:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:387:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:388:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:389:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:393:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:394:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:397:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:398:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
+// src/plugins/data/public/index.ts:401:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/query/state_sync/connect_to_query_state.ts:33:33 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/query/state_sync/connect_to_query_state.ts:37:1 - (ae-forgotten-export) The symbol "QueryStateChange" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/types.ts:52:5 - (ae-forgotten-export) The symbol "createFiltersFromValueClickAction" needs to be exported by the entry point index.d.ts
diff --git a/src/plugins/data/public/search/aggs/agg_groups.ts b/src/plugins/data/public/search/aggs/agg_groups.ts
index 9cebff76c9684..dec3397126e67 100644
--- a/src/plugins/data/public/search/aggs/agg_groups.ts
+++ b/src/plugins/data/public/search/aggs/agg_groups.ts
@@ -25,15 +25,17 @@ export const AggGroupNames = Object.freeze({
Metrics: 'metrics' as 'metrics',
None: 'none' as 'none',
});
-export type IAggGroupNames = $Values;
-type IAggGroupNamesMap = () => Record<'buckets' | 'metrics', string>;
+export type AggGroupName = $Values;
-export const aggGroupNamesMap: IAggGroupNamesMap = () => ({
+export const AggGroupLabels = {
+ [AggGroupNames.Buckets]: i18n.translate('data.search.aggs.aggGroups.bucketsText', {
+ defaultMessage: 'Buckets',
+ }),
[AggGroupNames.Metrics]: i18n.translate('data.search.aggs.aggGroups.metricsText', {
defaultMessage: 'Metrics',
}),
- [AggGroupNames.Buckets]: i18n.translate('data.search.aggs.aggGroups.bucketsText', {
- defaultMessage: 'Buckets',
+ [AggGroupNames.None]: i18n.translate('data.search.aggs.aggGroups.noneText', {
+ defaultMessage: 'None',
}),
-});
+};
diff --git a/src/plugins/data/public/search/aggs/filter/agg_type_filters.test.ts b/src/plugins/data/public/search/aggs/filter/agg_type_filters.test.ts
deleted file mode 100644
index 58f5aef0b9dfd..0000000000000
--- a/src/plugins/data/public/search/aggs/filter/agg_type_filters.test.ts
+++ /dev/null
@@ -1,62 +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 { IndexPattern } from '../../../index_patterns';
-import { AggTypeFilters } from './agg_type_filters';
-import { IAggConfig, IAggType } from '../types';
-
-describe('AggTypeFilters', () => {
- let registry: AggTypeFilters;
- const indexPattern = ({ id: '1234', fields: [], title: 'foo' } as unknown) as IndexPattern;
- const aggConfig = {} as IAggConfig;
-
- beforeEach(() => {
- registry = new AggTypeFilters();
- });
-
- it('should filter nothing without registered filters', async () => {
- const aggTypes = [{ name: 'count' }, { name: 'sum' }] as IAggType[];
- const filtered = registry.filter(aggTypes, indexPattern, aggConfig, []);
- expect(filtered).toEqual(aggTypes);
- });
-
- it('should pass all aggTypes to the registered filter', async () => {
- const aggTypes = [{ name: 'count' }, { name: 'sum' }] as IAggType[];
- const filter = jest.fn();
- registry.addFilter(filter);
- registry.filter(aggTypes, indexPattern, aggConfig, []);
- expect(filter).toHaveBeenCalledWith(aggTypes[0], indexPattern, aggConfig, []);
- expect(filter).toHaveBeenCalledWith(aggTypes[1], indexPattern, aggConfig, []);
- });
-
- it('should allow registered filters to filter out aggTypes', async () => {
- const aggTypes = [{ name: 'count' }, { name: 'sum' }, { name: 'avg' }] as IAggType[];
- let filtered = registry.filter(aggTypes, indexPattern, aggConfig, []);
- expect(filtered).toEqual(aggTypes);
-
- registry.addFilter(() => true);
- registry.addFilter(aggType => aggType.name !== 'count');
- filtered = registry.filter(aggTypes, indexPattern, aggConfig, []);
- expect(filtered).toEqual([aggTypes[1], aggTypes[2]]);
-
- registry.addFilter(aggType => aggType.name !== 'avg');
- filtered = registry.filter(aggTypes, indexPattern, aggConfig, []);
- expect(filtered).toEqual([aggTypes[1]]);
- });
-});
diff --git a/src/plugins/data/public/search/aggs/filter/agg_type_filters.ts b/src/plugins/data/public/search/aggs/filter/agg_type_filters.ts
deleted file mode 100644
index b8d192cd66b5a..0000000000000
--- a/src/plugins/data/public/search/aggs/filter/agg_type_filters.ts
+++ /dev/null
@@ -1,74 +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 { IndexPattern } from '../../../index_patterns';
-import { IAggConfig, IAggType } from '../types';
-
-type AggTypeFilter = (
- aggType: IAggType,
- indexPattern: IndexPattern,
- aggConfig: IAggConfig,
- aggFilter: string[]
-) => boolean;
-
-/**
- * A registry to store {@link AggTypeFilter} which are used to filter down
- * available aggregations for a specific visualization and {@link AggConfig}.
- */
-class AggTypeFilters {
- private filters = new Set();
-
- /**
- * Register a new {@link AggTypeFilter} with this registry.
- *
- * @param filter The filter to register.
- */
- public addFilter(filter: AggTypeFilter): void {
- this.filters.add(filter);
- }
-
- /**
- * Returns the {@link AggType|aggTypes} filtered by all registered filters.
- *
- * @param aggTypes A list of aggTypes that will be filtered down by this registry.
- * @param indexPattern The indexPattern for which this list should be filtered down.
- * @param aggConfig The aggConfig for which the returning list will be used.
- * @param schema
- * @return A filtered list of the passed aggTypes.
- */
- public filter(
- aggTypes: IAggType[],
- indexPattern: IndexPattern,
- aggConfig: IAggConfig,
- aggFilter: string[]
- ) {
- const allFilters = Array.from(this.filters);
- const allowedAggTypes = aggTypes.filter(aggType => {
- const isAggTypeAllowed = allFilters.every(filter =>
- filter(aggType, indexPattern, aggConfig, aggFilter)
- );
- return isAggTypeAllowed;
- });
- return allowedAggTypes;
- }
-}
-
-const aggTypeFilters = new AggTypeFilters();
-
-export { aggTypeFilters, AggTypeFilters };
diff --git a/src/plugins/data/public/search/aggs/filter/index.ts b/src/plugins/data/public/search/aggs/filter/index.ts
deleted file mode 100644
index 35d06807d0ec2..0000000000000
--- a/src/plugins/data/public/search/aggs/filter/index.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export { aggTypeFilters, AggTypeFilters } from './agg_type_filters';
-export { propFilter } from './prop_filter';
diff --git a/src/plugins/data/public/search/aggs/index.ts b/src/plugins/data/public/search/aggs/index.ts
index 5dfb6aeff8d14..1139d9c7ff722 100644
--- a/src/plugins/data/public/search/aggs/index.ts
+++ b/src/plugins/data/public/search/aggs/index.ts
@@ -24,7 +24,6 @@ export * from './agg_type';
export * from './agg_types';
export * from './agg_types_registry';
export * from './buckets';
-export * from './filter';
export * from './metrics';
export * from './param_types';
export * from './types';
diff --git a/src/plugins/data/public/search/aggs/param_types/field.ts b/src/plugins/data/public/search/aggs/param_types/field.ts
index 4d67f41905c5a..63dbed9cec612 100644
--- a/src/plugins/data/public/search/aggs/param_types/field.ts
+++ b/src/plugins/data/public/search/aggs/param_types/field.ts
@@ -21,7 +21,7 @@ import { i18n } from '@kbn/i18n';
import { IAggConfig } from '../agg_config';
import { SavedObjectNotFound } from '../../../../../../plugins/kibana_utils/public';
import { BaseParamType } from './base';
-import { propFilter } from '../filter';
+import { propFilter } from '../utils';
import { isNestedField, KBN_FIELD_TYPES } from '../../../../common';
import { Field as IndexPatternField } from '../../../index_patterns';
import { GetInternalStartServicesFn } from '../../../types';
diff --git a/src/plugins/data/public/search/aggs/param_types/filter/field_filters.test.ts b/src/plugins/data/public/search/aggs/param_types/filter/field_filters.test.ts
deleted file mode 100644
index f776a3deb23a1..0000000000000
--- a/src/plugins/data/public/search/aggs/param_types/filter/field_filters.test.ts
+++ /dev/null
@@ -1,61 +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 { AggTypeFieldFilters } from './field_filters';
-import { IAggConfig } from '../../agg_config';
-import { Field as IndexPatternField } from '../../../../index_patterns';
-
-describe('AggTypeFieldFilters', () => {
- let registry: AggTypeFieldFilters;
- const aggConfig = {} as IAggConfig;
-
- beforeEach(() => {
- registry = new AggTypeFieldFilters();
- });
-
- it('should filter nothing without registered filters', async () => {
- const fields = [{ name: 'foo' }, { name: 'bar' }] as IndexPatternField[];
- const filtered = registry.filter(fields, aggConfig);
- expect(filtered).toEqual(fields);
- });
-
- it('should pass all fields to the registered filter', async () => {
- const fields = [{ name: 'foo' }, { name: 'bar' }] as IndexPatternField[];
- const filter = jest.fn();
- registry.addFilter(filter);
- registry.filter(fields, aggConfig);
- expect(filter).toHaveBeenCalledWith(fields[0], aggConfig);
- expect(filter).toHaveBeenCalledWith(fields[1], aggConfig);
- });
-
- it('should allow registered filters to filter out fields', async () => {
- const fields = [{ name: 'foo' }, { name: 'bar' }] as IndexPatternField[];
- let filtered = registry.filter(fields, aggConfig);
- expect(filtered).toEqual(fields);
-
- registry.addFilter(() => true);
- registry.addFilter(field => field.name !== 'foo');
- filtered = registry.filter(fields, aggConfig);
- expect(filtered).toEqual([fields[1]]);
-
- registry.addFilter(field => field.name !== 'bar');
- filtered = registry.filter(fields, aggConfig);
- expect(filtered).toEqual([]);
- });
-});
diff --git a/src/plugins/data/public/search/aggs/param_types/filter/field_filters.ts b/src/plugins/data/public/search/aggs/param_types/filter/field_filters.ts
deleted file mode 100644
index 1cbf0c9ae3624..0000000000000
--- a/src/plugins/data/public/search/aggs/param_types/filter/field_filters.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { IndexPatternField } from 'src/plugins/data/public';
-import { IAggConfig } from '../../agg_config';
-
-type AggTypeFieldFilter = (field: IndexPatternField, aggConfig: IAggConfig) => boolean;
-
-/**
- * A registry to store {@link AggTypeFieldFilter} which are used to filter down
- * available fields for a specific visualization and {@link AggType}.
- */
-class AggTypeFieldFilters {
- private filters = new Set();
-
- /**
- * Register a new {@link AggTypeFieldFilter} with this registry.
- * This will be used by the {@link #filter|filter method}.
- *
- * @param filter The filter to register.
- */
- public addFilter(filter: AggTypeFieldFilter): void {
- this.filters.add(filter);
- }
-
- /**
- * Returns the {@link any|fields} filtered by all registered filters.
- *
- * @param fields An array of fields that will be filtered down by this registry.
- * @param aggConfig The aggConfig for which the returning list will be used.
- * @return A filtered list of the passed fields.
- */
- public filter(fields: IndexPatternField[], aggConfig: IAggConfig) {
- const allFilters = Array.from(this.filters);
- const allowedAggTypeFields = fields.filter(field => {
- const isAggTypeFieldAllowed = allFilters.every(filter => filter(field, aggConfig));
- return isAggTypeFieldAllowed;
- });
- return allowedAggTypeFields;
- }
-}
-
-const aggTypeFieldFilters = new AggTypeFieldFilters();
-
-export { aggTypeFieldFilters, AggTypeFieldFilters };
diff --git a/src/plugins/data/public/search/aggs/param_types/index.ts b/src/plugins/data/public/search/aggs/param_types/index.ts
index c9e8a9879f427..e25dd55dbd3f2 100644
--- a/src/plugins/data/public/search/aggs/param_types/index.ts
+++ b/src/plugins/data/public/search/aggs/param_types/index.ts
@@ -20,7 +20,6 @@
export * from './agg';
export * from './base';
export * from './field';
-export * from './filter';
export * from './json';
export * from './optioned';
export * from './string';
diff --git a/src/plugins/data/public/search/aggs/param_types/optioned.ts b/src/plugins/data/public/search/aggs/param_types/optioned.ts
index 9eb7ceda60711..45d0a65f69170 100644
--- a/src/plugins/data/public/search/aggs/param_types/optioned.ts
+++ b/src/plugins/data/public/search/aggs/param_types/optioned.ts
@@ -27,12 +27,6 @@ export interface OptionedValueProp {
isCompatible: (agg: IAggConfig) => boolean;
}
-export interface OptionedParamEditorProps {
- aggParam: {
- options: T[];
- };
-}
-
export class OptionedParamType extends BaseParamType {
options: OptionedValueProp[];
diff --git a/src/plugins/data/public/search/aggs/types.ts b/src/plugins/data/public/search/aggs/types.ts
index 95a7a45013567..1c5b5b458ce90 100644
--- a/src/plugins/data/public/search/aggs/types.ts
+++ b/src/plugins/data/public/search/aggs/types.ts
@@ -19,20 +19,13 @@
import { IndexPattern } from '../../index_patterns';
import {
- AggConfig,
AggConfigSerialized,
AggConfigs,
AggParamsTerms,
- AggType,
- aggTypeFieldFilters,
AggTypesRegistrySetup,
AggTypesRegistryStart,
CreateAggConfigParams,
- FieldParamType,
getCalculateAutoTimeExpression,
- MetricAggType,
- parentPipelineAggHelper,
- siblingPipelineAggHelper,
} from './';
export { IAggConfig, AggConfigSerialized } from './agg_config';
@@ -43,7 +36,7 @@ export { IFieldParamType } from './param_types';
export { IMetricAggType } from './metrics/metric_agg_type';
export { DateRangeKey } from './buckets/lib/date_range';
export { IpRangeKey } from './buckets/lib/ip_range';
-export { OptionedValueProp, OptionedParamEditorProps } from './param_types/optioned';
+export { OptionedValueProp } from './param_types/optioned';
/** @internal */
export interface SearchAggsSetup {
@@ -51,17 +44,6 @@ export interface SearchAggsSetup {
types: AggTypesRegistrySetup;
}
-/** @internal */
-export interface SearchAggsStartLegacy {
- AggConfig: typeof AggConfig;
- AggType: typeof AggType;
- aggTypeFieldFilters: typeof aggTypeFieldFilters;
- FieldParamType: typeof FieldParamType;
- MetricAggType: typeof MetricAggType;
- parentPipelineAggHelper: typeof parentPipelineAggHelper;
- siblingPipelineAggHelper: typeof siblingPipelineAggHelper;
-}
-
/** @internal */
export interface SearchAggsStart {
calculateAutoTimeExpression: ReturnType;
diff --git a/src/plugins/data/public/search/aggs/utils/index.ts b/src/plugins/data/public/search/aggs/utils/index.ts
index 23606bd109342..169d872b17d3a 100644
--- a/src/plugins/data/public/search/aggs/utils/index.ts
+++ b/src/plugins/data/public/search/aggs/utils/index.ts
@@ -18,4 +18,5 @@
*/
export * from './calculate_auto_time_expression';
+export * from './prop_filter';
export * from './to_angular_json';
diff --git a/src/plugins/data/public/search/aggs/filter/prop_filter.test.ts b/src/plugins/data/public/search/aggs/utils/prop_filter.test.ts
similarity index 100%
rename from src/plugins/data/public/search/aggs/filter/prop_filter.test.ts
rename to src/plugins/data/public/search/aggs/utils/prop_filter.test.ts
diff --git a/src/plugins/data/public/search/aggs/filter/prop_filter.ts b/src/plugins/data/public/search/aggs/utils/prop_filter.ts
similarity index 97%
rename from src/plugins/data/public/search/aggs/filter/prop_filter.ts
rename to src/plugins/data/public/search/aggs/utils/prop_filter.ts
index e6b5f3831e65d..01e98a68d3949 100644
--- a/src/plugins/data/public/search/aggs/filter/prop_filter.ts
+++ b/src/plugins/data/public/search/aggs/utils/prop_filter.ts
@@ -28,7 +28,7 @@ type FilterFunc
= (item: T[P]) => boolean;
*
* @returns the filter function which can be registered with angular
*/
-function propFilter
(prop: P) {
+export function propFilter
(prop: P) {
/**
* List filtering function which accepts an array or list of values that a property
* must contain
@@ -92,5 +92,3 @@ function propFilter
- For more license options please visit
- License Management.
-
-
-
-
- );
-}
diff --git a/x-pack/legacy/plugins/monitoring/public/filters/index.js b/x-pack/legacy/plugins/monitoring/public/filters/index.js
deleted file mode 100644
index a67770ff50dc8..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/filters/index.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { capitalize } from 'lodash';
-import { uiModules } from 'plugins/monitoring/np_imports/ui/modules';
-import { formatNumber, formatMetric } from 'plugins/monitoring/lib/format_number';
-import { extractIp } from 'plugins/monitoring/lib/extract_ip';
-
-const uiModule = uiModules.get('monitoring/filters', []);
-
-uiModule.filter('capitalize', function() {
- return function(input) {
- return capitalize(input.toLowerCase());
- };
-});
-
-uiModule.filter('formatNumber', function() {
- return formatNumber;
-});
-
-uiModule.filter('formatMetric', function() {
- return formatMetric;
-});
-
-uiModule.filter('extractIp', function() {
- return extractIp;
-});
diff --git a/x-pack/legacy/plugins/monitoring/public/hacks/toggle_app_link_in_nav.js b/x-pack/legacy/plugins/monitoring/public/hacks/toggle_app_link_in_nav.js
deleted file mode 100644
index 9448e826f3723..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/hacks/toggle_app_link_in_nav.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { uiModules } from 'ui/modules';
-import { npStart } from 'ui/new_platform';
-
-uiModules.get('monitoring/hacks').run(monitoringUiEnabled => {
- if (monitoringUiEnabled) {
- return;
- }
-
- npStart.core.chrome.navLinks.update('monitoring', { hidden: true });
-});
diff --git a/x-pack/legacy/plugins/monitoring/public/icons/monitoring.svg b/x-pack/legacy/plugins/monitoring/public/icons/monitoring.svg
deleted file mode 100644
index e00faca26a251..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/icons/monitoring.svg
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
diff --git a/x-pack/legacy/plugins/monitoring/public/legacy.ts b/x-pack/legacy/plugins/monitoring/public/legacy.ts
deleted file mode 100644
index 293b6ac7bd821..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/legacy.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import 'plugins/monitoring/filters';
-import 'plugins/monitoring/services/clusters';
-import 'plugins/monitoring/services/features';
-import 'plugins/monitoring/services/executor';
-import 'plugins/monitoring/services/license';
-import 'plugins/monitoring/services/title';
-import 'plugins/monitoring/services/breadcrumbs';
-import 'plugins/monitoring/directives/all';
-import 'plugins/monitoring/views/all';
-import { npSetup, npStart } from '../public/np_imports/legacy_imports';
-import { plugin } from './np_ready';
-import { localApplicationService } from '../../../../../src/legacy/core_plugins/kibana/public/local_application_service';
-
-const pluginInstance = plugin({} as any);
-pluginInstance.setup(npSetup.core, npSetup.plugins);
-pluginInstance.start(npStart.core, {
- ...npStart.plugins,
- __LEGACY: {
- localApplicationService,
- },
-});
diff --git a/x-pack/legacy/plugins/monitoring/public/np_imports/angular/angular_config.ts b/x-pack/legacy/plugins/monitoring/public/np_imports/angular/angular_config.ts
deleted file mode 100644
index d1849d9247985..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/np_imports/angular/angular_config.ts
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import {
- ICompileProvider,
- IHttpProvider,
- IHttpService,
- ILocationProvider,
- IModule,
- IRootScopeService,
-} from 'angular';
-import $ from 'jquery';
-import _, { cloneDeep, forOwn, get, set } from 'lodash';
-import * as Rx from 'rxjs';
-import { CoreStart, LegacyCoreStart } from 'kibana/public';
-
-const isSystemApiRequest = (request: any) =>
- Boolean(request && request.headers && !!request.headers['kbn-system-api']);
-
-export const configureAppAngularModule = (angularModule: IModule, newPlatform: LegacyCoreStart) => {
- const legacyMetadata = newPlatform.injectedMetadata.getLegacyMetadata();
-
- forOwn(newPlatform.injectedMetadata.getInjectedVars(), (val, name) => {
- if (name !== undefined) {
- // The legacy platform modifies some of these values, clone to an unfrozen object.
- angularModule.value(name, cloneDeep(val));
- }
- });
-
- angularModule
- .value('kbnVersion', newPlatform.injectedMetadata.getKibanaVersion())
- .value('buildNum', legacyMetadata.buildNum)
- .value('buildSha', legacyMetadata.buildSha)
- .value('serverName', legacyMetadata.serverName)
- .value('esUrl', getEsUrl(newPlatform))
- .value('uiCapabilities', newPlatform.application.capabilities)
- .config(setupCompileProvider(newPlatform))
- .config(setupLocationProvider())
- .config($setupXsrfRequestInterceptor(newPlatform))
- .run(capture$httpLoadingCount(newPlatform))
- .run($setupUICapabilityRedirect(newPlatform));
-};
-
-const getEsUrl = (newPlatform: CoreStart) => {
- const a = document.createElement('a');
- a.href = newPlatform.http.basePath.prepend('/elasticsearch');
- const protocolPort = /https/.test(a.protocol) ? 443 : 80;
- const port = a.port || protocolPort;
- return {
- host: a.hostname,
- port,
- protocol: a.protocol,
- pathname: a.pathname,
- };
-};
-
-const setupCompileProvider = (newPlatform: LegacyCoreStart) => (
- $compileProvider: ICompileProvider
-) => {
- if (!newPlatform.injectedMetadata.getLegacyMetadata().devMode) {
- $compileProvider.debugInfoEnabled(false);
- }
-};
-
-const setupLocationProvider = () => ($locationProvider: ILocationProvider) => {
- $locationProvider.html5Mode({
- enabled: false,
- requireBase: false,
- rewriteLinks: false,
- });
-
- $locationProvider.hashPrefix('');
-};
-
-const $setupXsrfRequestInterceptor = (newPlatform: LegacyCoreStart) => {
- const version = newPlatform.injectedMetadata.getLegacyMetadata().version;
-
- // Configure jQuery prefilter
- $.ajaxPrefilter(({ kbnXsrfToken = true }: any, originalOptions, jqXHR) => {
- if (kbnXsrfToken) {
- jqXHR.setRequestHeader('kbn-version', version);
- }
- });
-
- return ($httpProvider: IHttpProvider) => {
- // Configure $httpProvider interceptor
- $httpProvider.interceptors.push(() => {
- return {
- request(opts) {
- const { kbnXsrfToken = true } = opts as any;
- if (kbnXsrfToken) {
- set(opts, ['headers', 'kbn-version'], version);
- }
- return opts;
- },
- };
- });
- };
-};
-
-/**
- * Injected into angular module by ui/chrome angular integration
- * and adds a root-level watcher that will capture the count of
- * active $http requests on each digest loop and expose the count to
- * the core.loadingCount api
- * @param {Angular.Scope} $rootScope
- * @param {HttpService} $http
- * @return {undefined}
- */
-const capture$httpLoadingCount = (newPlatform: CoreStart) => (
- $rootScope: IRootScopeService,
- $http: IHttpService
-) => {
- newPlatform.http.addLoadingCountSource(
- new Rx.Observable(observer => {
- const unwatch = $rootScope.$watch(() => {
- const reqs = $http.pendingRequests || [];
- observer.next(reqs.filter(req => !isSystemApiRequest(req)).length);
- });
-
- return unwatch;
- })
- );
-};
-
-/**
- * integrates with angular to automatically redirect to home if required
- * capability is not met
- */
-const $setupUICapabilityRedirect = (newPlatform: CoreStart) => (
- $rootScope: IRootScopeService,
- $injector: any
-) => {
- const isKibanaAppRoute = window.location.pathname.endsWith('/app/kibana');
- // this feature only works within kibana app for now after everything is
- // switched to the application service, this can be changed to handle all
- // apps.
- if (!isKibanaAppRoute) {
- return;
- }
- $rootScope.$on(
- '$routeChangeStart',
- (event, { $$route: route }: { $$route?: { requireUICapability: boolean } } = {}) => {
- if (!route || !route.requireUICapability) {
- return;
- }
-
- if (!get(newPlatform.application.capabilities, route.requireUICapability)) {
- $injector.get('kbnUrl').change('/home');
- event.preventDefault();
- }
- }
- );
-};
diff --git a/x-pack/legacy/plugins/monitoring/public/np_imports/angular/index.ts b/x-pack/legacy/plugins/monitoring/public/np_imports/angular/index.ts
deleted file mode 100644
index 8fd8d170bbb40..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/np_imports/angular/index.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import angular, { IModule } from 'angular';
-
-import { AppMountContext, LegacyCoreStart } from 'kibana/public';
-
-// @ts-ignore TODO: change to absolute path
-import uiRoutes from 'plugins/monitoring/np_imports/ui/routes';
-// @ts-ignore TODO: change to absolute path
-import chrome from 'plugins/monitoring/np_imports/ui/chrome';
-// @ts-ignore TODO: change to absolute path
-import { uiModules } from 'plugins/monitoring/np_imports/ui/modules';
-// @ts-ignore TODO: change to absolute path
-import { registerTimefilterWithGlobalState } from 'plugins/monitoring/np_imports/ui/timefilter';
-import { configureAppAngularModule } from './angular_config';
-
-import { localAppModule, appModuleName } from './modules';
-
-export class AngularApp {
- private injector?: angular.auto.IInjectorService;
-
- constructor({ core }: AppMountContext, { element }: { element: HTMLElement }) {
- uiModules.addToModule();
- const app: IModule = localAppModule(core);
- app.config(($routeProvider: any) => {
- $routeProvider.eagerInstantiationEnabled(false);
- uiRoutes.addToProvider($routeProvider);
- });
- configureAppAngularModule(app, core as LegacyCoreStart);
- registerTimefilterWithGlobalState(app);
- const appElement = document.createElement('div');
- appElement.setAttribute('style', 'height: 100%');
- appElement.innerHTML = '';
- this.injector = angular.bootstrap(appElement, [appModuleName]);
- chrome.setInjector(this.injector);
- angular.element(element).append(appElement);
- }
-
- public destroy = () => {
- if (this.injector) {
- this.injector.get('$rootScope').$destroy();
- }
- };
-}
diff --git a/x-pack/legacy/plugins/monitoring/public/np_imports/angular/modules.ts b/x-pack/legacy/plugins/monitoring/public/np_imports/angular/modules.ts
deleted file mode 100644
index c6031cb220334..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/np_imports/angular/modules.ts
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import angular, { IWindowService } from 'angular';
-// required for `ngSanitize` angular module
-import 'angular-sanitize';
-import { i18nDirective, i18nFilter, I18nProvider } from '@kbn/i18n/angular';
-
-import { AppMountContext } from 'kibana/public';
-import { Storage } from '../../../../../../../src/plugins/kibana_utils/public';
-import {
- createTopNavDirective,
- createTopNavHelper,
-} from '../../../../../../../src/plugins/kibana_legacy/public';
-
-import {
- GlobalStateProvider,
- StateManagementConfigProvider,
- AppStateProvider,
- KbnUrlProvider,
- npStart,
-} from '../legacy_imports';
-
-// @ts-ignore
-import { PromiseServiceCreator } from './providers/promises';
-// @ts-ignore
-import { PrivateProvider } from './providers/private';
-import { getSafeForExternalLink } from '../../lib/get_safe_for_external_link';
-
-type IPrivate = (provider: (...injectable: any[]) => T) => T;
-
-export const appModuleName = 'monitoring';
-const thirdPartyAngularDependencies = ['ngSanitize', 'ngRoute', 'react'];
-
-export const localAppModule = (core: AppMountContext['core']) => {
- createLocalI18nModule();
- createLocalPrivateModule();
- createLocalPromiseModule();
- createLocalStorage();
- createLocalConfigModule(core);
- createLocalKbnUrlModule();
- createLocalStateModule();
- createLocalTopNavModule(npStart.plugins.navigation);
- createHrefModule(core);
-
- const appModule = angular.module(appModuleName, [
- ...thirdPartyAngularDependencies,
- 'monitoring/Config',
- 'monitoring/I18n',
- 'monitoring/Private',
- 'monitoring/TopNav',
- 'monitoring/State',
- 'monitoring/Storage',
- 'monitoring/href',
- 'monitoring/services',
- 'monitoring/filters',
- 'monitoring/directives',
- ]);
- return appModule;
-};
-
-function createLocalStateModule() {
- angular
- .module('monitoring/State', [
- 'monitoring/Private',
- 'monitoring/Config',
- 'monitoring/KbnUrl',
- 'monitoring/Promise',
- ])
- .factory('AppState', function(Private: IPrivate) {
- return Private(AppStateProvider);
- })
- .service('globalState', function(Private: IPrivate) {
- return Private(GlobalStateProvider);
- });
-}
-
-function createLocalKbnUrlModule() {
- angular
- .module('monitoring/KbnUrl', ['monitoring/Private', 'ngRoute'])
- .service('kbnUrl', (Private: IPrivate) => Private(KbnUrlProvider));
-}
-
-function createLocalConfigModule(core: AppMountContext['core']) {
- angular
- .module('monitoring/Config', ['monitoring/Private'])
- .provider('stateManagementConfig', StateManagementConfigProvider)
- .provider('config', () => {
- return {
- $get: () => ({
- get: core.uiSettings.get.bind(core.uiSettings),
- }),
- };
- });
-}
-
-function createLocalPromiseModule() {
- angular.module('monitoring/Promise', []).service('Promise', PromiseServiceCreator);
-}
-
-function createLocalStorage() {
- angular
- .module('monitoring/Storage', [])
- .service('localStorage', ($window: IWindowService) => new Storage($window.localStorage))
- .service('sessionStorage', ($window: IWindowService) => new Storage($window.sessionStorage))
- .service('sessionTimeout', () => {});
-}
-
-function createLocalPrivateModule() {
- angular.module('monitoring/Private', []).provider('Private', PrivateProvider);
-}
-
-function createLocalTopNavModule({ ui }: any) {
- angular
- .module('monitoring/TopNav', ['react'])
- .directive('kbnTopNav', createTopNavDirective)
- .directive('kbnTopNavHelper', createTopNavHelper(ui));
-}
-
-function createLocalI18nModule() {
- angular
- .module('monitoring/I18n', [])
- .provider('i18n', I18nProvider)
- .filter('i18n', i18nFilter)
- .directive('i18nId', i18nDirective);
-}
-
-function createHrefModule(core: AppMountContext['core']) {
- const name: string = 'kbnHref';
- angular.module('monitoring/href', []).directive(name, () => {
- return {
- restrict: 'A',
- link: {
- pre: (_$scope, _$el, $attr) => {
- $attr.$observe(name, val => {
- if (val) {
- const url = getSafeForExternalLink(val as string);
- $attr.$set('href', core.http.basePath.prepend(url));
- }
- });
- },
- },
- };
- });
-}
diff --git a/x-pack/legacy/plugins/monitoring/public/np_imports/angular/providers/promises.js b/x-pack/legacy/plugins/monitoring/public/np_imports/angular/providers/promises.js
deleted file mode 100644
index 22adccaf3db7f..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/np_imports/angular/providers/promises.js
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import _ from 'lodash';
-
-export function PromiseServiceCreator($q, $timeout) {
- function Promise(fn) {
- if (typeof this === 'undefined')
- throw new Error('Promise constructor must be called with "new"');
-
- const defer = $q.defer();
- try {
- fn(defer.resolve, defer.reject);
- } catch (e) {
- defer.reject(e);
- }
- return defer.promise;
- }
-
- Promise.all = Promise.props = $q.all;
- Promise.resolve = function(val) {
- const defer = $q.defer();
- defer.resolve(val);
- return defer.promise;
- };
- Promise.reject = function(reason) {
- const defer = $q.defer();
- defer.reject(reason);
- return defer.promise;
- };
- Promise.cast = $q.when;
- Promise.delay = function(ms) {
- return $timeout(_.noop, ms);
- };
- Promise.method = function(fn) {
- return function() {
- const args = Array.prototype.slice.call(arguments);
- return Promise.try(fn, args, this);
- };
- };
- Promise.nodeify = function(promise, cb) {
- promise.then(function(val) {
- cb(void 0, val);
- }, cb);
- };
- Promise.map = function(arr, fn) {
- return Promise.all(
- arr.map(function(i, el, list) {
- return Promise.try(fn, [i, el, list]);
- })
- );
- };
- Promise.each = function(arr, fn) {
- const queue = arr.slice(0);
- let i = 0;
- return (function next() {
- if (!queue.length) return arr;
- return Promise.try(fn, [arr.shift(), i++]).then(next);
- })();
- };
- Promise.is = function(obj) {
- // $q doesn't create instances of any constructor, promises are just objects with a then function
- // https://github.com/angular/angular.js/blob/58f5da86645990ef984353418cd1ed83213b111e/src/ng/q.js#L335
- return obj && typeof obj.then === 'function';
- };
- Promise.halt = _.once(function() {
- const promise = new Promise(() => {});
- promise.then = _.constant(promise);
- promise.catch = _.constant(promise);
- return promise;
- });
- Promise.try = function(fn, args, ctx) {
- if (typeof fn !== 'function') {
- return Promise.reject(new TypeError('fn must be a function'));
- }
-
- let value;
-
- if (Array.isArray(args)) {
- try {
- value = fn.apply(ctx, args);
- } catch (e) {
- return Promise.reject(e);
- }
- } else {
- try {
- value = fn.call(ctx, args);
- } catch (e) {
- return Promise.reject(e);
- }
- }
-
- return Promise.resolve(value);
- };
- Promise.fromNode = function(takesCbFn) {
- return new Promise(function(resolve, reject) {
- takesCbFn(function(err, ...results) {
- if (err) reject(err);
- else if (results.length > 1) resolve(results);
- else resolve(results[0]);
- });
- });
- };
- Promise.race = function(iterable) {
- return new Promise((resolve, reject) => {
- for (const i of iterable) {
- Promise.resolve(i).then(resolve, reject);
- }
- });
- };
-
- return Promise;
-}
diff --git a/x-pack/legacy/plugins/monitoring/public/np_imports/legacy_imports.ts b/x-pack/legacy/plugins/monitoring/public/np_imports/legacy_imports.ts
deleted file mode 100644
index 208b7e2acdb0f..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/np_imports/legacy_imports.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-/**
- * Last remaining 'ui/*' imports that will eventually be shimmed with their np alternatives
- */
-
-export { npSetup, npStart } from 'ui/new_platform';
-// @ts-ignore
-export { GlobalStateProvider } from 'ui/state_management/global_state';
-// @ts-ignore
-export { StateManagementConfigProvider } from 'ui/state_management/config_provider';
-// @ts-ignore
-export { AppStateProvider } from 'ui/state_management/app_state';
-// @ts-ignore
-export { EventsProvider } from 'ui/events';
-// @ts-ignore
-export { KbnUrlProvider } from 'ui/url';
-export { registerTimefilterWithGlobalStateFactory } from 'ui/timefilter/setup_router';
diff --git a/x-pack/legacy/plugins/monitoring/public/np_imports/ui/chrome.ts b/x-pack/legacy/plugins/monitoring/public/np_imports/ui/chrome.ts
deleted file mode 100644
index f0c5bacabecbf..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/np_imports/ui/chrome.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import angular from 'angular';
-import { npStart, npSetup } from '../legacy_imports';
-
-type OptionalInjector = void | angular.auto.IInjectorService;
-
-class Chrome {
- private injector?: OptionalInjector;
-
- public setInjector = (injector: OptionalInjector): void => void (this.injector = injector);
- public dangerouslyGetActiveInjector = (): OptionalInjector => this.injector;
-
- public getBasePath = (): string => npStart.core.http.basePath.get();
-
- public getInjected = (name?: string, defaultValue?: any): string | unknown => {
- const { getInjectedVar, getInjectedVars } = npSetup.core.injectedMetadata;
- return name ? getInjectedVar(name, defaultValue) : getInjectedVars();
- };
-
- public get breadcrumbs() {
- const set = (...args: any[]) => npStart.core.chrome.setBreadcrumbs.apply(this, args as any);
- return { set };
- }
-}
-
-const chrome = new Chrome();
-
-export default chrome; // eslint-disable-line import/no-default-export
diff --git a/x-pack/legacy/plugins/monitoring/public/np_imports/ui/modules.ts b/x-pack/legacy/plugins/monitoring/public/np_imports/ui/modules.ts
deleted file mode 100644
index 70201a7906110..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/np_imports/ui/modules.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import angular from 'angular';
-
-type PrivateProvider = (...args: any) => any;
-interface Provider {
- name: string;
- provider: PrivateProvider;
-}
-
-class Modules {
- private _services: Provider[] = [];
- private _filters: Provider[] = [];
- private _directives: Provider[] = [];
-
- public get = (_name: string, _dep?: string[]) => {
- return this;
- };
-
- public service = (...args: any) => {
- this._services.push(args);
- };
-
- public filter = (...args: any) => {
- this._filters.push(args);
- };
-
- public directive = (...args: any) => {
- this._directives.push(args);
- };
-
- public addToModule = () => {
- angular.module('monitoring/services', []);
- angular.module('monitoring/filters', []);
- angular.module('monitoring/directives', []);
-
- this._services.forEach(args => {
- angular.module('monitoring/services').service.apply(null, args as any);
- });
-
- this._filters.forEach(args => {
- angular.module('monitoring/filters').filter.apply(null, args as any);
- });
-
- this._directives.forEach(args => {
- angular.module('monitoring/directives').directive.apply(null, args as any);
- });
- };
-}
-
-export const uiModules = new Modules();
diff --git a/x-pack/legacy/plugins/monitoring/public/np_imports/ui/timefilter.ts b/x-pack/legacy/plugins/monitoring/public/np_imports/ui/timefilter.ts
deleted file mode 100644
index e28699bd126b9..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/np_imports/ui/timefilter.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { IModule, IRootScopeService } from 'angular';
-import { npStart, registerTimefilterWithGlobalStateFactory } from '../legacy_imports';
-
-const {
- core: { uiSettings },
-} = npStart;
-export const { timefilter } = npStart.plugins.data.query.timefilter;
-
-uiSettings.overrideLocalDefault(
- 'timepicker:refreshIntervalDefaults',
- JSON.stringify({ value: 10000, pause: false })
-);
-uiSettings.overrideLocalDefault(
- 'timepicker:timeDefaults',
- JSON.stringify({ from: 'now-1h', to: 'now' })
-);
-
-export const registerTimefilterWithGlobalState = (app: IModule) => {
- app.run((globalState: any, $rootScope: IRootScopeService) => {
- globalState.fetch();
- globalState.$inheritedGlobalState = true;
- globalState.save();
- registerTimefilterWithGlobalStateFactory(timefilter, globalState, $rootScope);
- });
-};
diff --git a/x-pack/legacy/plugins/monitoring/public/np_ready/plugin.ts b/x-pack/legacy/plugins/monitoring/public/np_ready/plugin.ts
deleted file mode 100644
index 5598a7a51cf42..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/np_ready/plugin.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { App, CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'kibana/public';
-
-export class MonitoringPlugin implements Plugin {
- constructor(ctx: PluginInitializerContext) {}
-
- public setup(core: CoreSetup, plugins: any) {
- const app: App = {
- id: 'monitoring',
- title: 'Monitoring',
- mount: async (context, params) => {
- const { AngularApp } = await import('../np_imports/angular');
- const monitoringApp = new AngularApp(context, params);
- return monitoringApp.destroy;
- },
- };
-
- core.application.register(app);
- }
-
- public start(core: CoreStart, plugins: any) {}
- public stop() {}
-}
diff --git a/x-pack/legacy/plugins/monitoring/public/register_feature.ts b/x-pack/legacy/plugins/monitoring/public/register_feature.ts
deleted file mode 100644
index 9b72e01a19394..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/register_feature.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { i18n } from '@kbn/i18n';
-import chrome from 'ui/chrome';
-import { npSetup } from 'ui/new_platform';
-import { FeatureCatalogueCategory } from '../../../../../src/plugins/home/public';
-
-const {
- plugins: { home },
-} = npSetup;
-
-if (chrome.getInjected('monitoringUiEnabled')) {
- home.featureCatalogue.register({
- id: 'monitoring',
- title: i18n.translate('xpack.monitoring.monitoringTitle', {
- defaultMessage: 'Monitoring',
- }),
- description: i18n.translate('xpack.monitoring.monitoringDescription', {
- defaultMessage: 'Track the real-time health and performance of your Elastic Stack.',
- }),
- icon: 'monitoringApp',
- path: '/app/monitoring',
- showOnHomePage: true,
- category: FeatureCatalogueCategory.ADMIN,
- });
-}
diff --git a/x-pack/legacy/plugins/monitoring/public/services/breadcrumbs.js b/x-pack/legacy/plugins/monitoring/public/services/breadcrumbs.js
deleted file mode 100644
index d0fe600386307..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/services/breadcrumbs.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { uiModules } from 'plugins/monitoring/np_imports/ui/modules';
-import { breadcrumbsProvider } from './breadcrumbs_provider';
-const uiModule = uiModules.get('monitoring/breadcrumbs', []);
-uiModule.service('breadcrumbs', breadcrumbsProvider);
diff --git a/x-pack/legacy/plugins/monitoring/public/services/executor.js b/x-pack/legacy/plugins/monitoring/public/services/executor.js
deleted file mode 100644
index 5004cd0238012..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/services/executor.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { uiModules } from 'plugins/monitoring/np_imports/ui/modules';
-import { executorProvider } from './executor_provider';
-const uiModule = uiModules.get('monitoring/executor', []);
-uiModule.service('$executor', executorProvider);
diff --git a/x-pack/legacy/plugins/monitoring/public/views/kibana/instance/index.js b/x-pack/legacy/plugins/monitoring/public/views/kibana/instance/index.js
deleted file mode 100644
index 6535bd7410445..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/views/kibana/instance/index.js
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-/*
- * Kibana Instance
- */
-import React from 'react';
-import { get } from 'lodash';
-import uiRoutes from 'plugins/monitoring/np_imports/ui/routes';
-import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler';
-import { routeInitProvider } from 'plugins/monitoring/lib/route_init';
-import template from './index.html';
-import { timefilter } from 'plugins/monitoring/np_imports/ui/timefilter';
-import {
- EuiPage,
- EuiPageBody,
- EuiPageContent,
- EuiSpacer,
- EuiFlexGrid,
- EuiFlexItem,
- EuiPanel,
-} from '@elastic/eui';
-import { MonitoringTimeseriesContainer } from '../../../components/chart';
-import { DetailStatus } from 'plugins/monitoring/components/kibana/detail_status';
-import { I18nContext } from 'ui/i18n';
-import { MonitoringViewBaseController } from '../../base_controller';
-import { CODE_PATH_KIBANA } from '../../../../common/constants';
-
-function getPageData($injector) {
- const $http = $injector.get('$http');
- const globalState = $injector.get('globalState');
- const $route = $injector.get('$route');
- const url = `../api/monitoring/v1/clusters/${globalState.cluster_uuid}/kibana/${$route.current.params.uuid}`;
- const timeBounds = timefilter.getBounds();
-
- return $http
- .post(url, {
- ccs: globalState.ccs,
- timeRange: {
- min: timeBounds.min.toISOString(),
- max: timeBounds.max.toISOString(),
- },
- })
- .then(response => response.data)
- .catch(err => {
- const Private = $injector.get('Private');
- const ajaxErrorHandlers = Private(ajaxErrorHandlersProvider);
- return ajaxErrorHandlers(err);
- });
-}
-
-uiRoutes.when('/kibana/instances/:uuid', {
- template,
- resolve: {
- clusters(Private) {
- const routeInit = Private(routeInitProvider);
- return routeInit({ codePaths: [CODE_PATH_KIBANA] });
- },
- pageData: getPageData,
- },
- controllerAs: 'monitoringKibanaInstanceApp',
- controller: class extends MonitoringViewBaseController {
- constructor($injector, $scope) {
- super({
- title: `Kibana - ${get($scope.pageData, 'kibanaSummary.name')}`,
- defaultData: {},
- getPageData,
- reactNodeId: 'monitoringKibanaInstanceApp',
- $scope,
- $injector,
- });
-
- $scope.$watch(
- () => this.data,
- data => {
- if (!data || !data.metrics) {
- return;
- }
-
- this.setTitle(`Kibana - ${get(data, 'kibanaSummary.name')}`);
-
- this.renderReact(
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
- }
- );
- }
- },
-});
diff --git a/x-pack/legacy/plugins/monitoring/public/views/loading/index.html b/x-pack/legacy/plugins/monitoring/public/views/loading/index.html
deleted file mode 100644
index 11da26a0ceed2..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/views/loading/index.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/x-pack/legacy/plugins/monitoring/public/views/loading/index.js b/x-pack/legacy/plugins/monitoring/public/views/loading/index.js
deleted file mode 100644
index 0488683845a7d..0000000000000
--- a/x-pack/legacy/plugins/monitoring/public/views/loading/index.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import React from 'react';
-import { render, unmountComponentAtNode } from 'react-dom';
-import { PageLoading } from 'plugins/monitoring/components';
-import uiRoutes from 'plugins/monitoring/np_imports/ui/routes';
-import { I18nContext } from 'ui/i18n';
-import template from './index.html';
-import { CODE_PATH_LICENSE } from '../../../common/constants';
-
-const REACT_DOM_ID = 'monitoringLoadingReactApp';
-
-uiRoutes.when('/loading', {
- template,
- controller: class {
- constructor($injector, $scope) {
- const monitoringClusters = $injector.get('monitoringClusters');
- const kbnUrl = $injector.get('kbnUrl');
-
- $scope.$on('$destroy', () => {
- unmountComponentAtNode(document.getElementById(REACT_DOM_ID));
- });
-
- $scope.$$postDigest(() => {
- this.renderReact();
- });
-
- monitoringClusters(undefined, undefined, [CODE_PATH_LICENSE]).then(clusters => {
- if (clusters && clusters.length) {
- kbnUrl.changePath('/home');
- return;
- }
- kbnUrl.changePath('/no-data');
- return;
- });
- }
-
- renderReact() {
- render(
-
-
- ,
- document.getElementById(REACT_DOM_ID)
- );
- }
- },
-});
diff --git a/x-pack/legacy/plugins/monitoring/ui_exports.js b/x-pack/legacy/plugins/monitoring/ui_exports.js
deleted file mode 100644
index e0c04411ef46b..0000000000000
--- a/x-pack/legacy/plugins/monitoring/ui_exports.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { i18n } from '@kbn/i18n';
-import { resolve } from 'path';
-import {
- MONITORING_CONFIG_ALERTING_EMAIL_ADDRESS,
- KIBANA_ALERTING_ENABLED,
-} from './common/constants';
-import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/utils';
-
-/**
- * Configuration of dependency objects for the UI, which are needed for the
- * Monitoring UI app and views and data for outside the monitoring
- * app (injectDefaultVars and hacks)
- * @return {Object} data per Kibana plugin uiExport schema
- */
-export const getUiExports = () => {
- const uiSettingDefaults = {};
- if (KIBANA_ALERTING_ENABLED) {
- uiSettingDefaults[MONITORING_CONFIG_ALERTING_EMAIL_ADDRESS] = {
- name: i18n.translate('xpack.monitoring.alertingEmailAddress.name', {
- defaultMessage: 'Alerting email address',
- }),
- value: '',
- description: i18n.translate('xpack.monitoring.alertingEmailAddress.description', {
- defaultMessage: `The default email address to receive alerts from Stack Monitoring`,
- }),
- category: ['monitoring'],
- };
- }
-
- return {
- app: {
- title: i18n.translate('xpack.monitoring.stackMonitoringTitle', {
- defaultMessage: 'Stack Monitoring',
- }),
- order: 9002,
- description: i18n.translate('xpack.monitoring.uiExportsDescription', {
- defaultMessage: 'Monitoring for Elastic Stack',
- }),
- icon: 'plugins/monitoring/icons/monitoring.svg',
- euiIconType: 'monitoringApp',
- linkToLastSubUrl: false,
- main: 'plugins/monitoring/legacy',
- category: DEFAULT_APP_CATEGORIES.management,
- },
- injectDefaultVars(server) {
- const config = server.config();
- return {
- monitoringUiEnabled: config.get('monitoring.ui.enabled'),
- monitoringLegacyEmailAddress: config.get(
- 'monitoring.cluster_alerts.email_notifications.email_address'
- ),
- };
- },
- uiSettingDefaults,
- hacks: ['plugins/monitoring/hacks/toggle_app_link_in_nav'],
- home: ['plugins/monitoring/register_feature'],
- styleSheetPaths: resolve(__dirname, 'public/index.scss'),
- };
-};
diff --git a/x-pack/legacy/plugins/xpack_main/server/routes/api/v1/settings.js b/x-pack/legacy/plugins/xpack_main/server/routes/api/v1/settings.js
index c830fc9fcd483..99071a2f85e13 100644
--- a/x-pack/legacy/plugins/xpack_main/server/routes/api/v1/settings.js
+++ b/x-pack/legacy/plugins/xpack_main/server/routes/api/v1/settings.js
@@ -6,7 +6,7 @@
import { boomify } from 'boom';
import { get } from 'lodash';
-import { KIBANA_SETTINGS_TYPE } from '../../../../../monitoring/common/constants';
+import { KIBANA_SETTINGS_TYPE } from '../../../../../../../plugins/monitoring/common/constants';
const getClusterUuid = async callCluster => {
const { cluster_uuid: uuid } = await callCluster('info', { filterPath: 'cluster_uuid' });
diff --git a/x-pack/plugins/actions/README.md b/x-pack/plugins/actions/README.md
index decd170ca5dd6..4c8cc3aa503e6 100644
--- a/x-pack/plugins/actions/README.md
+++ b/x-pack/plugins/actions/README.md
@@ -28,7 +28,7 @@ Table of Contents
- [RESTful API](#restful-api)
- [`POST /api/action`: Create action](#post-apiaction-create-action)
- [`DELETE /api/action/{id}`: Delete action](#delete-apiactionid-delete-action)
- - [`GET /api/action/_getAll`: Get all actions](#get-apiaction-get-all-actions)
+ - [`GET /api/action/_getAll`: Get all actions](#get-apiactiongetall-get-all-actions)
- [`GET /api/action/{id}`: Get action](#get-apiactionid-get-action)
- [`GET /api/action/types`: List action types](#get-apiactiontypes-list-action-types)
- [`PUT /api/action/{id}`: Update action](#put-apiactionid-update-action)
@@ -64,6 +64,12 @@ Table of Contents
- [`config`](#config-6)
- [`secrets`](#secrets-6)
- [`params`](#params-6)
+ - [`subActionParams (pushToService)`](#subactionparams-pushtoservice)
+ - [Jira](#jira)
+ - [`config`](#config-7)
+ - [`secrets`](#secrets-7)
+ - [`params`](#params-7)
+ - [`subActionParams (pushToService)`](#subactionparams-pushtoservice-1)
- [Command Line Utility](#command-line-utility)
## Terminology
@@ -143,8 +149,8 @@ This is the primary function for an action type. Whenever the action needs to ex
| actionId | The action saved object id that the action type is executing for. |
| config | The decrypted configuration given to an action. This comes from the action saved object that is partially or fully encrypted within the data store. If you would like to validate the config before being passed to the executor, define `validate.config` within the action type. |
| params | Parameters for the execution. These will be given at execution time by either an alert or manually provided when calling the plugin provided execute function. |
-| services.callCluster(path, opts) | Use this to do Elasticsearch queries on the cluster Kibana connects to. This function is the same as any other `callCluster` in Kibana but runs in the context of the user who is calling the action when security is enabled.|
-| services.getScopedCallCluster | This function scopes an instance of CallCluster by returning a `callCluster(path, opts)` function that runs in the context of the user who is calling the action when security is enabled. This must only be called with instances of CallCluster provided by core.|
+| services.callCluster(path, opts) | Use this to do Elasticsearch queries on the cluster Kibana connects to. This function is the same as any other `callCluster` in Kibana but runs in the context of the user who is calling the action when security is enabled. |
+| services.getScopedCallCluster | This function scopes an instance of CallCluster by returning a `callCluster(path, opts)` function that runs in the context of the user who is calling the action when security is enabled. This must only be called with instances of CallCluster provided by core. |
| services.savedObjectsClient | This is an instance of the saved objects client. This provides the ability to do CRUD on any saved objects within the same space the alert lives in.