Merge branch 'master' into reporting/test-better
This commit is contained in:
commit
890128c47d
463 changed files with 6625 additions and 3897 deletions
20
.eslintrc.js
20
.eslintrc.js
|
@ -69,26 +69,6 @@ module.exports = {
|
||||||
'jsx-a11y/no-onchange': 'off',
|
'jsx-a11y/no-onchange': 'off',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
files: ['src/legacy/core_plugins/expressions/**/*.{js,ts,tsx}'],
|
|
||||||
rules: {
|
|
||||||
'react-hooks/exhaustive-deps': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: [
|
|
||||||
'src/legacy/core_plugins/vis_default_editor/public/components/controls/**/*.{ts,tsx}',
|
|
||||||
],
|
|
||||||
rules: {
|
|
||||||
'react-hooks/exhaustive-deps': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: ['src/legacy/ui/public/vis/**/*.{js,ts,tsx}'],
|
|
||||||
rules: {
|
|
||||||
'react-hooks/exhaustive-deps': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
files: ['src/plugins/es_ui_shared/**/*.{js,ts,tsx}'],
|
files: ['src/plugins/es_ui_shared/**/*.{js,ts,tsx}'],
|
||||||
rules: {
|
rules: {
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
"tileMap": "src/legacy/core_plugins/tile_map",
|
"tileMap": "src/legacy/core_plugins/tile_map",
|
||||||
"timelion": ["src/legacy/core_plugins/timelion", "src/legacy/core_plugins/vis_type_timelion", "src/plugins/timelion"],
|
"timelion": ["src/legacy/core_plugins/timelion", "src/legacy/core_plugins/vis_type_timelion", "src/plugins/timelion"],
|
||||||
"uiActions": "src/plugins/ui_actions",
|
"uiActions": "src/plugins/ui_actions",
|
||||||
"visDefaultEditor": "src/legacy/core_plugins/vis_default_editor",
|
"visDefaultEditor": "src/plugins/vis_default_editor",
|
||||||
"visTypeMarkdown": "src/legacy/core_plugins/vis_type_markdown",
|
"visTypeMarkdown": "src/legacy/core_plugins/vis_type_markdown",
|
||||||
"visTypeMetric": "src/legacy/core_plugins/vis_type_metric",
|
"visTypeMetric": "src/legacy/core_plugins/vis_type_metric",
|
||||||
"visTypeTable": "src/legacy/core_plugins/vis_type_table",
|
"visTypeTable": "src/legacy/core_plugins/vis_type_table",
|
||||||
|
|
BIN
docs/apm/images/service-maps-java.png
Normal file
BIN
docs/apm/images/service-maps-java.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 524 KiB |
BIN
docs/apm/images/service-maps.png
Normal file
BIN
docs/apm/images/service-maps.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 483 KiB |
48
docs/apm/service-maps.asciidoc
Normal file
48
docs/apm/service-maps.asciidoc
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
[[service-maps]]
|
||||||
|
=== Service maps
|
||||||
|
|
||||||
|
beta::[]
|
||||||
|
|
||||||
|
A service map is a real-time diagram of the interactions occurring in your application’s architecture.
|
||||||
|
It allows you to easily visualize data flow and high-level statistics, like average transaction duration,
|
||||||
|
requests per minute, errors per minute, and metrics, allowing you to quickly assess the status of your services.
|
||||||
|
|
||||||
|
Our beta offering creates two types of service maps:
|
||||||
|
|
||||||
|
* Global: All services and connections are shown.
|
||||||
|
* Service-specific: Selecting a specific service will highlight it's connections.
|
||||||
|
|
||||||
|
[role="screenshot"]
|
||||||
|
image::apm/images/service-maps.png[Example view of service maps in the APM app in Kibana]
|
||||||
|
|
||||||
|
[float]
|
||||||
|
[[visualize-your-architecture]]
|
||||||
|
=== Visualize your architecture
|
||||||
|
|
||||||
|
Select the **Service Map** tab to get started.
|
||||||
|
By default, all services and connections are shown.
|
||||||
|
Whether your onboarding a new engineer, or just trying to grasp the big picture,
|
||||||
|
click around, zoom in and out, and begin to visualize how your services are connected.
|
||||||
|
|
||||||
|
If there's a specific service that interests you, select that service to highlight its connections.
|
||||||
|
Clicking **Focus map** will refocus the map on that specific service and lock the connection highlighting.
|
||||||
|
From here, select **Service Details**, or click on the **Transaction** tab to jump to the Transaction overview.
|
||||||
|
You can also use the tabs at the top of the page to easily jump to the **Errors** or **Metrics** overview.
|
||||||
|
|
||||||
|
While it's not possible to query in service maps, it is possible to filter by environment.
|
||||||
|
This can be useful if you have two or more services, in separate environments, but with the same name.
|
||||||
|
Use the environment drop down to only see the data you're interested in, like `dev` or `production`.
|
||||||
|
|
||||||
|
[role="screenshot"]
|
||||||
|
image::apm/images/service-maps-java.png[Example view of service maps with Java highlighted in the APM app in Kibana]
|
||||||
|
|
||||||
|
[float]
|
||||||
|
[[service-maps-legend]]
|
||||||
|
=== Legend
|
||||||
|
|
||||||
|
Nodes appear on the map in one of two shapes:
|
||||||
|
|
||||||
|
* **Circle**: Instrumented services. Interior icons are based on the language of the agent used.
|
||||||
|
* **Diamond**: Databases, external, and messaging. Interior icons represent the generic type,
|
||||||
|
with specific icons for known entities, like Elasticsearch.
|
||||||
|
Type and subtype are based on `span.type`, and `span.subtype`.
|
|
@ -31,6 +31,8 @@ include::transactions.asciidoc[]
|
||||||
|
|
||||||
include::spans.asciidoc[]
|
include::spans.asciidoc[]
|
||||||
|
|
||||||
|
include::service-maps.asciidoc[]
|
||||||
|
|
||||||
include::errors.asciidoc[]
|
include::errors.asciidoc[]
|
||||||
|
|
||||||
include::metrics.asciidoc[]
|
include::metrics.asciidoc[]
|
||||||
|
|
|
@ -45,10 +45,15 @@ Registering a feature consists of the following fields. For more information, co
|
||||||
|An array of applications this feature enables. Typically, all of your plugin's apps (from `uiExports`) will be included here.
|
|An array of applications this feature enables. Typically, all of your plugin's apps (from `uiExports`) will be included here.
|
||||||
|
|
||||||
|`privileges` (required)
|
|`privileges` (required)
|
||||||
|{repo}blob/{branch}/x-pack/plugins/features/server/feature.ts[`FeatureWithAllOrReadPrivileges`].
|
|{repo}blob/{branch}/x-pack/plugins/features/common/feature.ts[`FeatureConfig`].
|
||||||
|See <<example-1-canvas,Example 1>> and <<example-2-dev-tools,Example 2>>
|
|See <<example-1-canvas,Example 1>> and <<example-2-dev-tools,Example 2>>
|
||||||
|The set of privileges this feature requires to function.
|
|The set of privileges this feature requires to function.
|
||||||
|
|
||||||
|
|`subFeatures` (optional)
|
||||||
|
|{repo}blob/{branch}/x-pack/plugins/features/common/feature.ts[`FeatureConfig`].
|
||||||
|
|See <<example-3-discover,Example 3>>
|
||||||
|
|The set of subfeatures that enables finer access control than the `all` and `read` feature privileges. These options are only available in the Gold subscription level and higher.
|
||||||
|
|
||||||
|`icon`
|
|`icon`
|
||||||
|`string`
|
|`string`
|
||||||
|"discoverApp"
|
|"discoverApp"
|
||||||
|
@ -192,3 +197,78 @@ server.route({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
[[example-3-discover]]
|
||||||
|
==== Example 3: Discover
|
||||||
|
|
||||||
|
Discover takes advantage of subfeature privileges to allow fine-grained access control. In this example,
|
||||||
|
a single "Create Short URLs" subfeature privilege is defined, which allows users to grant access to this feature without having to grant the `all` privilege to Discover. In other words, you can grant `read` access to Discover, and also grant the ability to create short URLs.
|
||||||
|
|
||||||
|
["source","javascript"]
|
||||||
|
-----------
|
||||||
|
init(server) {
|
||||||
|
const xpackMainPlugin = server.plugins.xpack_main;
|
||||||
|
xpackMainPlugin.registerFeature({
|
||||||
|
{
|
||||||
|
id: 'discover',
|
||||||
|
name: i18n.translate('xpack.features.discoverFeatureName', {
|
||||||
|
defaultMessage: 'Discover',
|
||||||
|
}),
|
||||||
|
order: 100,
|
||||||
|
icon: 'discoverApp',
|
||||||
|
navLinkId: 'kibana:discover',
|
||||||
|
app: ['kibana'],
|
||||||
|
catalogue: ['discover'],
|
||||||
|
privileges: {
|
||||||
|
all: {
|
||||||
|
app: ['kibana'],
|
||||||
|
catalogue: ['discover'],
|
||||||
|
savedObject: {
|
||||||
|
all: ['search', 'query'],
|
||||||
|
read: ['index-pattern'],
|
||||||
|
},
|
||||||
|
ui: ['show', 'save', 'saveQuery'],
|
||||||
|
},
|
||||||
|
read: {
|
||||||
|
app: ['kibana'],
|
||||||
|
catalogue: ['discover'],
|
||||||
|
savedObject: {
|
||||||
|
all: [],
|
||||||
|
read: ['index-pattern', 'search', 'query'],
|
||||||
|
},
|
||||||
|
ui: ['show'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
subFeatures: [
|
||||||
|
{
|
||||||
|
name: i18n.translate('xpack.features.ossFeatures.discoverShortUrlSubFeatureName', {
|
||||||
|
defaultMessage: 'Short URLs',
|
||||||
|
}),
|
||||||
|
privilegeGroups: [
|
||||||
|
{
|
||||||
|
groupType: 'independent',
|
||||||
|
privileges: [
|
||||||
|
{
|
||||||
|
id: 'url_create',
|
||||||
|
name: i18n.translate(
|
||||||
|
'xpack.features.ossFeatures.discoverCreateShortUrlPrivilegeName',
|
||||||
|
{
|
||||||
|
defaultMessage: 'Create Short URLs',
|
||||||
|
}
|
||||||
|
),
|
||||||
|
includeIn: 'all',
|
||||||
|
savedObject: {
|
||||||
|
all: ['url'],
|
||||||
|
read: [],
|
||||||
|
},
|
||||||
|
ui: ['createShortUrl'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
-----------
|
||||||
|
|
|
@ -43,6 +43,10 @@ Assigning a feature privilege grants access to a specific feature.
|
||||||
`all`:: Grants full read-write access.
|
`all`:: Grants full read-write access.
|
||||||
`read`:: Grants read-only access.
|
`read`:: Grants read-only access.
|
||||||
|
|
||||||
|
===== Sub-feature privileges
|
||||||
|
Some features allow for finer access control than the `all` and `read` privileges.
|
||||||
|
This additional level of control is available in the Gold subscription level and higher.
|
||||||
|
|
||||||
===== Assigning feature privileges
|
===== Assigning feature privileges
|
||||||
From the role management screen:
|
From the role management screen:
|
||||||
|
|
||||||
|
@ -62,7 +66,8 @@ PUT /api/security/role/my_kibana_role
|
||||||
{
|
{
|
||||||
"base": [],
|
"base": [],
|
||||||
"feature": {
|
"feature": {
|
||||||
"dashboard": ["all"]
|
"visualize": ["all"],
|
||||||
|
"dashboard": ["read", "url_create"]
|
||||||
},
|
},
|
||||||
"spaces": ["marketing"]
|
"spaces": ["marketing"]
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 496 KiB After Width: | Height: | Size: 636 KiB |
|
@ -30,7 +30,7 @@ import {
|
||||||
EuiSelect,
|
EuiSelect,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
|
|
||||||
import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import { IIndexPattern } from 'src/plugins/data/public';
|
import { IIndexPattern } from 'src/plugins/data/public';
|
||||||
import { ControlEditor } from './control_editor';
|
import { ControlEditor } from './control_editor';
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { EuiForm, EuiFormRow, EuiSwitch } from '@elastic/eui';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import { EuiSwitchEvent } from '@elastic/eui';
|
import { EuiSwitchEvent } from '@elastic/eui';
|
||||||
|
|
||||||
import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
|
|
||||||
interface OptionsTabParams {
|
interface OptionsTabParams {
|
||||||
updateFiltersOnChange: boolean;
|
updateFiltersOnChange: boolean;
|
||||||
|
|
|
@ -201,7 +201,6 @@ function createDocTableModule() {
|
||||||
.directive('docTable', createDocTableDirective)
|
.directive('docTable', createDocTableDirective)
|
||||||
.directive('kbnTableHeader', createTableHeaderDirective)
|
.directive('kbnTableHeader', createTableHeaderDirective)
|
||||||
.directive('toolBarPagerText', createToolBarPagerTextDirective)
|
.directive('toolBarPagerText', createToolBarPagerTextDirective)
|
||||||
.directive('toolBarPagerText', createToolBarPagerTextDirective)
|
|
||||||
.directive('kbnTableRow', createTableRowDirective)
|
.directive('kbnTableRow', createTableRowDirective)
|
||||||
.directive('toolBarPagerButtons', createToolBarPagerButtonsDirective)
|
.directive('toolBarPagerButtons', createToolBarPagerButtonsDirective)
|
||||||
.directive('kbnInfiniteScroll', createInfiniteScrollDirective)
|
.directive('kbnInfiniteScroll', createInfiniteScrollDirective)
|
||||||
|
|
|
@ -50,8 +50,6 @@ export const [getUrlTracker, setUrlTracker] = createGetterSetter<{
|
||||||
setTrackedUrl: (url: string) => void;
|
setTrackedUrl: (url: string) => void;
|
||||||
}>('urlTracker');
|
}>('urlTracker');
|
||||||
|
|
||||||
// EXPORT legacy static dependencies, should be migrated when available in a new version;
|
|
||||||
export { wrapInI18nContext } from 'ui/i18n';
|
|
||||||
import { search } from '../../../../../plugins/data/public';
|
import { search } from '../../../../../plugins/data/public';
|
||||||
import { createGetterSetter } from '../../../../../plugins/kibana_utils/common';
|
import { createGetterSetter } from '../../../../../plugins/kibana_utils/common';
|
||||||
export const { getRequestInspectorStats, getResponseInspectorStats, tabifyAggResponse } = search;
|
export const { getRequestInspectorStats, getResponseInspectorStats, tabifyAggResponse } = search;
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage, I18nProvider } from '@kbn/i18n/react';
|
||||||
import {
|
import {
|
||||||
EuiButtonEmpty,
|
EuiButtonEmpty,
|
||||||
EuiFieldNumber,
|
EuiFieldNumber,
|
||||||
|
@ -88,77 +88,83 @@ export function ActionBar({
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={onSubmit}>
|
<I18nProvider>
|
||||||
{isSuccessor && <EuiSpacer size="s" />}
|
<form onSubmit={onSubmit}>
|
||||||
{isSuccessor && showWarning && <ActionBarWarning docCount={docCountAvailable} type={type} />}
|
{isSuccessor && <EuiSpacer size="s" />}
|
||||||
{isSuccessor && showWarning && <EuiSpacer size="s" />}
|
{isSuccessor && showWarning && (
|
||||||
<EuiFlexGroup direction="row" gutterSize="s" responsive={false}>
|
<ActionBarWarning docCount={docCountAvailable} type={type} />
|
||||||
<EuiFlexItem grow={false}>
|
)}
|
||||||
<EuiButtonEmpty
|
{isSuccessor && showWarning && <EuiSpacer size="s" />}
|
||||||
data-test-subj={`${type}LoadMoreButton`}
|
<EuiFlexGroup direction="row" gutterSize="s" responsive={false}>
|
||||||
iconType={isSuccessor ? 'arrowDown' : 'arrowUp'}
|
<EuiFlexItem grow={false}>
|
||||||
isDisabled={isDisabled}
|
<EuiButtonEmpty
|
||||||
isLoading={isLoading}
|
data-test-subj={`${type}LoadMoreButton`}
|
||||||
onClick={() => {
|
iconType={isSuccessor ? 'arrowDown' : 'arrowUp'}
|
||||||
const value = newDocCount + defaultStepSize;
|
isDisabled={isDisabled}
|
||||||
if (isValid(value)) {
|
isLoading={isLoading}
|
||||||
setNewDocCount(value);
|
onClick={() => {
|
||||||
onChangeCount(value);
|
const value = newDocCount + defaultStepSize;
|
||||||
}
|
if (isValid(value)) {
|
||||||
}}
|
setNewDocCount(value);
|
||||||
flush="right"
|
onChangeCount(value);
|
||||||
>
|
|
||||||
<FormattedMessage id="kbn.context.loadButtonLabel" defaultMessage="Load" />
|
|
||||||
</EuiButtonEmpty>
|
|
||||||
</EuiFlexItem>
|
|
||||||
<EuiFlexItem grow={false}>
|
|
||||||
<EuiFormRow>
|
|
||||||
<EuiFieldNumber
|
|
||||||
aria-label={
|
|
||||||
isSuccessor
|
|
||||||
? i18n.translate('kbn.context.olderDocumentsAriaLabel', {
|
|
||||||
defaultMessage: 'Number of older documents',
|
|
||||||
})
|
|
||||||
: i18n.translate('kbn.context.newerDocumentsAriaLabel', {
|
|
||||||
defaultMessage: 'Number of newer documents',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
className="cxtSizePicker"
|
|
||||||
data-test-subj={`${type}CountPicker`}
|
|
||||||
disabled={isDisabled}
|
|
||||||
min={MIN_CONTEXT_SIZE}
|
|
||||||
max={MAX_CONTEXT_SIZE}
|
|
||||||
onChange={ev => {
|
|
||||||
setNewDocCount(ev.target.valueAsNumber);
|
|
||||||
}}
|
|
||||||
onBlur={() => {
|
|
||||||
if (newDocCount !== docCount && isValid(newDocCount)) {
|
|
||||||
onChangeCount(newDocCount);
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
type="number"
|
flush="right"
|
||||||
value={newDocCount >= 0 ? newDocCount : ''}
|
>
|
||||||
/>
|
<FormattedMessage id="kbn.context.loadButtonLabel" defaultMessage="Load" />
|
||||||
</EuiFormRow>
|
</EuiButtonEmpty>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
<EuiFlexItem>
|
<EuiFlexItem grow={false}>
|
||||||
<EuiFormRow displayOnly>
|
<EuiFormRow>
|
||||||
{isSuccessor ? (
|
<EuiFieldNumber
|
||||||
<FormattedMessage
|
aria-label={
|
||||||
id="kbn.context.olderDocumentsDescription"
|
isSuccessor
|
||||||
defaultMessage="older documents"
|
? i18n.translate('kbn.context.olderDocumentsAriaLabel', {
|
||||||
|
defaultMessage: 'Number of older documents',
|
||||||
|
})
|
||||||
|
: i18n.translate('kbn.context.newerDocumentsAriaLabel', {
|
||||||
|
defaultMessage: 'Number of newer documents',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
className="cxtSizePicker"
|
||||||
|
data-test-subj={`${type}CountPicker`}
|
||||||
|
disabled={isDisabled}
|
||||||
|
min={MIN_CONTEXT_SIZE}
|
||||||
|
max={MAX_CONTEXT_SIZE}
|
||||||
|
onChange={ev => {
|
||||||
|
setNewDocCount(ev.target.valueAsNumber);
|
||||||
|
}}
|
||||||
|
onBlur={() => {
|
||||||
|
if (newDocCount !== docCount && isValid(newDocCount)) {
|
||||||
|
onChangeCount(newDocCount);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
type="number"
|
||||||
|
value={newDocCount >= 0 ? newDocCount : ''}
|
||||||
/>
|
/>
|
||||||
) : (
|
</EuiFormRow>
|
||||||
<FormattedMessage
|
</EuiFlexItem>
|
||||||
id="kbn.context.newerDocumentsDescription"
|
<EuiFlexItem>
|
||||||
defaultMessage="newer documents"
|
<EuiFormRow displayOnly>
|
||||||
/>
|
{isSuccessor ? (
|
||||||
)}
|
<FormattedMessage
|
||||||
</EuiFormRow>
|
id="kbn.context.olderDocumentsDescription"
|
||||||
</EuiFlexItem>
|
defaultMessage="older documents"
|
||||||
</EuiFlexGroup>
|
/>
|
||||||
{!isSuccessor && showWarning && <ActionBarWarning docCount={docCountAvailable} type={type} />}
|
) : (
|
||||||
{!isSuccessor && <EuiSpacer size="s" />}
|
<FormattedMessage
|
||||||
</form>
|
id="kbn.context.newerDocumentsDescription"
|
||||||
|
defaultMessage="newer documents"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</EuiFormRow>
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
{!isSuccessor && showWarning && (
|
||||||
|
<ActionBarWarning docCount={docCountAvailable} type={type} />
|
||||||
|
)}
|
||||||
|
{!isSuccessor && <EuiSpacer size="s" />}
|
||||||
|
</form>
|
||||||
|
</I18nProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { getAngularModule, wrapInI18nContext } from '../../../../../kibana_services';
|
import { getAngularModule } from '../../../../../kibana_services';
|
||||||
import { ActionBar } from './action_bar';
|
import { ActionBar } from './action_bar';
|
||||||
|
|
||||||
getAngularModule().directive('contextActionBar', function(reactDirective: any) {
|
getAngularModule().directive('contextActionBar', function(reactDirective: any) {
|
||||||
return reactDirective(wrapInI18nContext(ActionBar));
|
return reactDirective(ActionBar);
|
||||||
});
|
});
|
||||||
|
|
|
@ -20,16 +20,12 @@
|
||||||
import { DiscoverNoResults } from './no_results';
|
import { DiscoverNoResults } from './no_results';
|
||||||
import { DiscoverUninitialized } from './uninitialized';
|
import { DiscoverUninitialized } from './uninitialized';
|
||||||
import { DiscoverHistogram } from './histogram';
|
import { DiscoverHistogram } from './histogram';
|
||||||
import { getAngularModule, wrapInI18nContext } from '../../../kibana_services';
|
import { getAngularModule } from '../../../kibana_services';
|
||||||
|
|
||||||
const app = getAngularModule();
|
const app = getAngularModule();
|
||||||
|
|
||||||
app.directive('discoverNoResults', reactDirective =>
|
app.directive('discoverNoResults', reactDirective => reactDirective(DiscoverNoResults));
|
||||||
reactDirective(wrapInI18nContext(DiscoverNoResults))
|
|
||||||
);
|
|
||||||
|
|
||||||
app.directive('discoverUninitialized', reactDirective =>
|
app.directive('discoverUninitialized', reactDirective => reactDirective(DiscoverUninitialized));
|
||||||
reactDirective(wrapInI18nContext(DiscoverUninitialized))
|
|
||||||
);
|
|
||||||
|
|
||||||
app.directive('discoverHistogram', reactDirective => reactDirective(DiscoverHistogram));
|
app.directive('discoverHistogram', reactDirective => reactDirective(DiscoverHistogram));
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage, I18nProvider } from '@kbn/i18n/react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -247,29 +247,31 @@ export class DiscoverNoResults extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<I18nProvider>
|
||||||
<EuiSpacer size="xl" />
|
<Fragment>
|
||||||
|
<EuiSpacer size="xl" />
|
||||||
|
|
||||||
<EuiFlexGroup justifyContent="center">
|
<EuiFlexGroup justifyContent="center">
|
||||||
<EuiFlexItem grow={false} className="dscNoResults">
|
<EuiFlexItem grow={false} className="dscNoResults">
|
||||||
<EuiCallOut
|
<EuiCallOut
|
||||||
title={
|
title={
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id="kbn.discover.noResults.searchExamples.noResultsMatchSearchCriteriaTitle"
|
id="kbn.discover.noResults.searchExamples.noResultsMatchSearchCriteriaTitle"
|
||||||
defaultMessage="No results match your search criteria"
|
defaultMessage="No results match your search criteria"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
color="warning"
|
color="warning"
|
||||||
iconType="help"
|
iconType="help"
|
||||||
data-test-subj="discoverNoResults"
|
data-test-subj="discoverNoResults"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{shardFailuresMessage}
|
{shardFailuresMessage}
|
||||||
{timeFieldMessage}
|
{timeFieldMessage}
|
||||||
{luceneQueryMessage}
|
{luceneQueryMessage}
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
</EuiFlexGroup>
|
</EuiFlexGroup>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
</I18nProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage, I18nProvider } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import { EuiButton, EuiEmptyPrompt, EuiPage, EuiPageBody, EuiPageContent } from '@elastic/eui';
|
import { EuiButton, EuiEmptyPrompt, EuiPage, EuiPageBody, EuiPageContent } from '@elastic/eui';
|
||||||
|
|
||||||
|
@ -28,38 +28,40 @@ interface Props {
|
||||||
|
|
||||||
export const DiscoverUninitialized = ({ onRefresh }: Props) => {
|
export const DiscoverUninitialized = ({ onRefresh }: Props) => {
|
||||||
return (
|
return (
|
||||||
<EuiPage>
|
<I18nProvider>
|
||||||
<EuiPageBody>
|
<EuiPage>
|
||||||
<EuiPageContent horizontalPosition="center">
|
<EuiPageBody>
|
||||||
<EuiEmptyPrompt
|
<EuiPageContent horizontalPosition="center">
|
||||||
iconType="discoverApp"
|
<EuiEmptyPrompt
|
||||||
title={
|
iconType="discoverApp"
|
||||||
<h2>
|
title={
|
||||||
<FormattedMessage
|
<h2>
|
||||||
id="kbn.discover.uninitializedTitle"
|
<FormattedMessage
|
||||||
defaultMessage="Start searching"
|
id="kbn.discover.uninitializedTitle"
|
||||||
/>
|
defaultMessage="Start searching"
|
||||||
</h2>
|
/>
|
||||||
}
|
</h2>
|
||||||
body={
|
}
|
||||||
<p>
|
body={
|
||||||
<FormattedMessage
|
<p>
|
||||||
id="kbn.discover.uninitializedText"
|
<FormattedMessage
|
||||||
defaultMessage="Write a query, add some filters, or simply hit Refresh to retrieve results for the current query."
|
id="kbn.discover.uninitializedText"
|
||||||
/>
|
defaultMessage="Write a query, add some filters, or simply hit Refresh to retrieve results for the current query."
|
||||||
</p>
|
/>
|
||||||
}
|
</p>
|
||||||
actions={
|
}
|
||||||
<EuiButton color="primary" fill onClick={onRefresh}>
|
actions={
|
||||||
<FormattedMessage
|
<EuiButton color="primary" fill onClick={onRefresh}>
|
||||||
id="kbn.discover.uninitializedRefreshButtonText"
|
<FormattedMessage
|
||||||
defaultMessage="Refresh data"
|
id="kbn.discover.uninitializedRefreshButtonText"
|
||||||
/>
|
defaultMessage="Refresh data"
|
||||||
</EuiButton>
|
/>
|
||||||
}
|
</EuiButton>
|
||||||
/>
|
}
|
||||||
</EuiPageContent>
|
/>
|
||||||
</EuiPageBody>
|
</EuiPageContent>
|
||||||
</EuiPage>
|
</EuiPageBody>
|
||||||
|
</EuiPage>
|
||||||
|
</I18nProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { getAngularModule, wrapInI18nContext, getServices } from '../../kibana_services';
|
import { getAngularModule, getServices } from '../../kibana_services';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { getRootBreadcrumbs } from '../helpers/breadcrumbs';
|
import { getRootBreadcrumbs } from '../helpers/breadcrumbs';
|
||||||
import html from './doc.html';
|
import html from './doc.html';
|
||||||
|
@ -30,7 +30,7 @@ const { timefilter } = getServices();
|
||||||
const app = getAngularModule();
|
const app = getAngularModule();
|
||||||
app.directive('discoverDoc', function(reactDirective: any) {
|
app.directive('discoverDoc', function(reactDirective: any) {
|
||||||
return reactDirective(
|
return reactDirective(
|
||||||
wrapInI18nContext(Doc),
|
Doc,
|
||||||
[
|
[
|
||||||
['id', { watchDepth: 'value' }],
|
['id', { watchDepth: 'value' }],
|
||||||
['index', { watchDepth: 'value' }],
|
['index', { watchDepth: 'value' }],
|
||||||
|
|
|
@ -16,14 +16,13 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { wrapInI18nContext } from '../../../../../kibana_services';
|
|
||||||
import { ToolBarPagerText } from './tool_bar_pager_text';
|
import { ToolBarPagerText } from './tool_bar_pager_text';
|
||||||
import { ToolBarPagerButtons } from './tool_bar_pager_buttons';
|
import { ToolBarPagerButtons } from './tool_bar_pager_buttons';
|
||||||
|
|
||||||
export function createToolBarPagerTextDirective(reactDirective: any) {
|
export function createToolBarPagerTextDirective(reactDirective: any) {
|
||||||
return reactDirective(wrapInI18nContext(ToolBarPagerText));
|
return reactDirective(ToolBarPagerText);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createToolBarPagerButtonsDirective(reactDirective: any) {
|
export function createToolBarPagerButtonsDirective(reactDirective: any) {
|
||||||
return reactDirective(wrapInI18nContext(ToolBarPagerButtons));
|
return reactDirective(ToolBarPagerButtons);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage, I18nProvider } from '@kbn/i18n/react';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
startItem: number;
|
startItem: number;
|
||||||
|
@ -27,12 +27,14 @@ interface Props {
|
||||||
|
|
||||||
export function ToolBarPagerText({ startItem, endItem, totalItems }: Props) {
|
export function ToolBarPagerText({ startItem, endItem, totalItems }: Props) {
|
||||||
return (
|
return (
|
||||||
<div className="kuiToolBarText" data-test-subj="toolBarPagerText">
|
<I18nProvider>
|
||||||
<FormattedMessage
|
<div className="kuiToolBarText" data-test-subj="toolBarPagerText">
|
||||||
id="kbn.docTable.pagerControl.pagesCountLabel"
|
<FormattedMessage
|
||||||
defaultMessage="{startItem}–{endItem} of {totalItems}"
|
id="kbn.docTable.pagerControl.pagesCountLabel"
|
||||||
values={{ startItem, endItem, totalItems }}
|
defaultMessage="{startItem}–{endItem} of {totalItems}"
|
||||||
/>
|
values={{ startItem, endItem, totalItems }}
|
||||||
</div>
|
/>
|
||||||
|
</div>
|
||||||
|
</I18nProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,13 +17,13 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { TableHeader } from './table_header/table_header';
|
import { TableHeader } from './table_header/table_header';
|
||||||
import { wrapInI18nContext, getServices } from '../../../../kibana_services';
|
import { getServices } from '../../../../kibana_services';
|
||||||
|
|
||||||
export function createTableHeaderDirective(reactDirective: any) {
|
export function createTableHeaderDirective(reactDirective: any) {
|
||||||
const { uiSettings: config } = getServices();
|
const { uiSettings: config } = getServices();
|
||||||
|
|
||||||
return reactDirective(
|
return reactDirective(
|
||||||
wrapInI18nContext(TableHeader),
|
TableHeader,
|
||||||
[
|
[
|
||||||
['columns', { watchDepth: 'collection' }],
|
['columns', { watchDepth: 'collection' }],
|
||||||
['hideTimeColumn', { watchDepth: 'value' }],
|
['hideTimeColumn', { watchDepth: 'value' }],
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage, I18nProvider } from '@kbn/i18n/react';
|
||||||
import { EuiCallOut, EuiLink, EuiLoadingSpinner, EuiPageContent } from '@elastic/eui';
|
import { EuiCallOut, EuiLink, EuiLoadingSpinner, EuiPageContent } from '@elastic/eui';
|
||||||
import { IndexPatternsContract } from 'src/plugins/data/public';
|
import { IndexPatternsContract } from 'src/plugins/data/public';
|
||||||
import { ElasticRequestState, useEsDocSearch } from './use_es_doc_search';
|
import { ElasticRequestState, useEsDocSearch } from './use_es_doc_search';
|
||||||
|
@ -65,83 +65,85 @@ export function Doc(props: DocProps) {
|
||||||
const [reqState, hit, indexPattern] = useEsDocSearch(props);
|
const [reqState, hit, indexPattern] = useEsDocSearch(props);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EuiPageContent>
|
<I18nProvider>
|
||||||
{reqState === ElasticRequestState.NotFoundIndexPattern && (
|
<EuiPageContent>
|
||||||
<EuiCallOut
|
{reqState === ElasticRequestState.NotFoundIndexPattern && (
|
||||||
color="danger"
|
<EuiCallOut
|
||||||
data-test-subj={`doc-msg-notFoundIndexPattern`}
|
color="danger"
|
||||||
iconType="alert"
|
data-test-subj={`doc-msg-notFoundIndexPattern`}
|
||||||
title={
|
iconType="alert"
|
||||||
<FormattedMessage
|
title={
|
||||||
id="kbn.doc.failedToLocateIndexPattern"
|
<FormattedMessage
|
||||||
defaultMessage="No index pattern matches ID {indexPatternId}"
|
id="kbn.doc.failedToLocateIndexPattern"
|
||||||
values={{ indexPatternId: props.indexPatternId }}
|
defaultMessage="No index pattern matches ID {indexPatternId}"
|
||||||
/>
|
values={{ indexPatternId: props.indexPatternId }}
|
||||||
}
|
/>
|
||||||
/>
|
}
|
||||||
)}
|
|
||||||
{reqState === ElasticRequestState.NotFound && (
|
|
||||||
<EuiCallOut
|
|
||||||
color="danger"
|
|
||||||
data-test-subj={`doc-msg-notFound`}
|
|
||||||
iconType="alert"
|
|
||||||
title={
|
|
||||||
<FormattedMessage
|
|
||||||
id="kbn.doc.failedToLocateDocumentDescription"
|
|
||||||
defaultMessage="Cannot find document"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id="kbn.doc.couldNotFindDocumentsDescription"
|
|
||||||
defaultMessage="No documents match that ID."
|
|
||||||
/>
|
/>
|
||||||
</EuiCallOut>
|
)}
|
||||||
)}
|
{reqState === ElasticRequestState.NotFound && (
|
||||||
|
<EuiCallOut
|
||||||
{reqState === ElasticRequestState.Error && (
|
color="danger"
|
||||||
<EuiCallOut
|
data-test-subj={`doc-msg-notFound`}
|
||||||
color="danger"
|
iconType="alert"
|
||||||
data-test-subj={`doc-msg-error`}
|
title={
|
||||||
iconType="alert"
|
<FormattedMessage
|
||||||
title={
|
id="kbn.doc.failedToLocateDocumentDescription"
|
||||||
<FormattedMessage
|
defaultMessage="Cannot find document"
|
||||||
id="kbn.doc.failedToExecuteQueryDescription"
|
/>
|
||||||
defaultMessage="Cannot run search"
|
}
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id="kbn.doc.somethingWentWrongDescription"
|
|
||||||
defaultMessage="{indexName} is missing."
|
|
||||||
values={{ indexName: props.index }}
|
|
||||||
/>{' '}
|
|
||||||
<EuiLink
|
|
||||||
href={`https://www.elastic.co/guide/en/elasticsearch/reference/${
|
|
||||||
getServices().metadata.branch
|
|
||||||
}/indices-exists.html`}
|
|
||||||
target="_blank"
|
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id="kbn.doc.somethingWentWrongDescriptionAddon"
|
id="kbn.doc.couldNotFindDocumentsDescription"
|
||||||
defaultMessage="Please ensure the index exists."
|
defaultMessage="No documents match that ID."
|
||||||
/>
|
/>
|
||||||
</EuiLink>
|
</EuiCallOut>
|
||||||
</EuiCallOut>
|
)}
|
||||||
)}
|
|
||||||
|
|
||||||
{reqState === ElasticRequestState.Loading && (
|
{reqState === ElasticRequestState.Error && (
|
||||||
<EuiCallOut data-test-subj={`doc-msg-loading`}>
|
<EuiCallOut
|
||||||
<EuiLoadingSpinner size="m" />{' '}
|
color="danger"
|
||||||
<FormattedMessage id="kbn.doc.loadingDescription" defaultMessage="Loading…" />
|
data-test-subj={`doc-msg-error`}
|
||||||
</EuiCallOut>
|
iconType="alert"
|
||||||
)}
|
title={
|
||||||
|
<FormattedMessage
|
||||||
|
id="kbn.doc.failedToExecuteQueryDescription"
|
||||||
|
defaultMessage="Cannot run search"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id="kbn.doc.somethingWentWrongDescription"
|
||||||
|
defaultMessage="{indexName} is missing."
|
||||||
|
values={{ indexName: props.index }}
|
||||||
|
/>{' '}
|
||||||
|
<EuiLink
|
||||||
|
href={`https://www.elastic.co/guide/en/elasticsearch/reference/${
|
||||||
|
getServices().metadata.branch
|
||||||
|
}/indices-exists.html`}
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id="kbn.doc.somethingWentWrongDescriptionAddon"
|
||||||
|
defaultMessage="Please ensure the index exists."
|
||||||
|
/>
|
||||||
|
</EuiLink>
|
||||||
|
</EuiCallOut>
|
||||||
|
)}
|
||||||
|
|
||||||
{reqState === ElasticRequestState.Found && hit !== null && indexPattern && (
|
{reqState === ElasticRequestState.Loading && (
|
||||||
<div data-test-subj="doc-hit">
|
<EuiCallOut data-test-subj={`doc-msg-loading`}>
|
||||||
<DocViewer hit={hit} indexPattern={indexPattern} />
|
<EuiLoadingSpinner size="m" />{' '}
|
||||||
</div>
|
<FormattedMessage id="kbn.doc.loadingDescription" defaultMessage="Loading…" />
|
||||||
)}
|
</EuiCallOut>
|
||||||
</EuiPageContent>
|
)}
|
||||||
|
|
||||||
|
{reqState === ElasticRequestState.Found && hit !== null && indexPattern && (
|
||||||
|
<div data-test-subj="doc-hit">
|
||||||
|
<DocViewer hit={hit} indexPattern={indexPattern} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</EuiPageContent>
|
||||||
|
</I18nProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage, I18nProvider } from '@kbn/i18n/react';
|
||||||
import { EuiFlexGroup, EuiFlexItem, EuiCallOut, EuiCodeBlock, EuiSpacer } from '@elastic/eui';
|
import { EuiFlexGroup, EuiFlexItem, EuiCallOut, EuiCodeBlock, EuiSpacer } from '@elastic/eui';
|
||||||
import { getAngularModule, wrapInI18nContext, getServices } from '../../../kibana_services';
|
import { getAngularModule, getServices } from '../../../kibana_services';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
fetchError: {
|
fetchError: {
|
||||||
|
@ -72,26 +72,28 @@ const DiscoverFetchError = ({ fetchError }: Props) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<I18nProvider>
|
||||||
<EuiSpacer size="xl" />
|
<Fragment>
|
||||||
|
<EuiSpacer size="xl" />
|
||||||
|
|
||||||
<EuiFlexGroup justifyContent="center" data-test-subj="discoverFetchError">
|
<EuiFlexGroup justifyContent="center" data-test-subj="discoverFetchError">
|
||||||
<EuiFlexItem grow={false} className="discoverFetchError">
|
<EuiFlexItem grow={false} className="discoverFetchError">
|
||||||
<EuiCallOut title={fetchError.message} color="danger" iconType="cross">
|
<EuiCallOut title={fetchError.message} color="danger" iconType="cross">
|
||||||
{body}
|
{body}
|
||||||
|
|
||||||
<EuiCodeBlock>{fetchError.error}</EuiCodeBlock>
|
<EuiCodeBlock>{fetchError.error}</EuiCodeBlock>
|
||||||
</EuiCallOut>
|
</EuiCallOut>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
</EuiFlexGroup>
|
</EuiFlexGroup>
|
||||||
|
|
||||||
<EuiSpacer size="xl" />
|
<EuiSpacer size="xl" />
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
</I18nProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createFetchErrorDirective(reactDirective: any) {
|
export function createFetchErrorDirective(reactDirective: any) {
|
||||||
return reactDirective(wrapInI18nContext(DiscoverFetchError));
|
return reactDirective(DiscoverFetchError);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAngularModule().directive('discoverFetchError', createFetchErrorDirective);
|
getAngularModule().directive('discoverFetchError', createFetchErrorDirective);
|
||||||
|
|
|
@ -20,7 +20,7 @@ import React, { useCallback, useEffect, useState, useMemo } from 'react';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { EuiButtonIcon, EuiTitle } from '@elastic/eui';
|
import { EuiButtonIcon, EuiTitle } from '@elastic/eui';
|
||||||
import { sortBy } from 'lodash';
|
import { sortBy } from 'lodash';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage, I18nProvider } from '@kbn/i18n/react';
|
||||||
import { DiscoverField } from './discover_field';
|
import { DiscoverField } from './discover_field';
|
||||||
import { DiscoverIndexPattern } from './discover_index_pattern';
|
import { DiscoverIndexPattern } from './discover_index_pattern';
|
||||||
import { DiscoverFieldSearch } from './discover_field_search';
|
import { DiscoverFieldSearch } from './discover_field_search';
|
||||||
|
@ -162,165 +162,175 @@ export function DiscoverSidebar({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section
|
<I18nProvider>
|
||||||
className="sidebar-list"
|
<section
|
||||||
aria-label={i18n.translate(
|
className="sidebar-list"
|
||||||
'kbn.discover.fieldChooser.filter.indexAndFieldsSectionAriaLabel',
|
aria-label={i18n.translate(
|
||||||
{
|
'kbn.discover.fieldChooser.filter.indexAndFieldsSectionAriaLabel',
|
||||||
defaultMessage: 'Index and fields',
|
{
|
||||||
}
|
defaultMessage: 'Index and fields',
|
||||||
)}
|
}
|
||||||
>
|
)}
|
||||||
<DiscoverIndexPattern
|
>
|
||||||
selectedIndexPattern={selectedIndexPattern}
|
<DiscoverIndexPattern
|
||||||
setIndexPattern={setIndexPattern}
|
selectedIndexPattern={selectedIndexPattern}
|
||||||
indexPatternList={sortBy(indexPatternList, o => o.attributes.title)}
|
setIndexPattern={setIndexPattern}
|
||||||
/>
|
indexPatternList={sortBy(indexPatternList, o => o.attributes.title)}
|
||||||
<div className="dscSidebar__item">
|
/>
|
||||||
<form>
|
<div className="dscSidebar__item">
|
||||||
<DiscoverFieldSearch
|
<form>
|
||||||
onChange={onChangeFieldSearch}
|
<DiscoverFieldSearch
|
||||||
value={fieldFilterState.name}
|
onChange={onChangeFieldSearch}
|
||||||
types={fieldTypes}
|
value={fieldFilterState.name}
|
||||||
/>
|
types={fieldTypes}
|
||||||
</form>
|
/>
|
||||||
</div>
|
</form>
|
||||||
<div className="sidebar-list">
|
</div>
|
||||||
{fields.length > 0 && (
|
<div className="sidebar-list">
|
||||||
<>
|
{fields.length > 0 && (
|
||||||
<EuiTitle size="xxxs" id="selected_fields">
|
<>
|
||||||
<h3>
|
<EuiTitle size="xxxs" id="selected_fields">
|
||||||
<FormattedMessage
|
|
||||||
id="kbn.discover.fieldChooser.filter.selectedFieldsTitle"
|
|
||||||
defaultMessage="Selected fields"
|
|
||||||
/>
|
|
||||||
</h3>
|
|
||||||
</EuiTitle>
|
|
||||||
<ul
|
|
||||||
className="dscSidebarList dscFieldList--selected"
|
|
||||||
aria-labelledby="selected_fields"
|
|
||||||
data-test-subj={`fieldList-selected`}
|
|
||||||
>
|
|
||||||
{selectedFields.map((field: IndexPatternField, idx: number) => {
|
|
||||||
return (
|
|
||||||
<li key={`field${idx}`} data-attr-field={field.name} className="dscSidebar__item">
|
|
||||||
<DiscoverField
|
|
||||||
field={field}
|
|
||||||
indexPattern={selectedIndexPattern}
|
|
||||||
onAddField={onAddField}
|
|
||||||
onRemoveField={onRemoveField}
|
|
||||||
onAddFilter={onAddFilter}
|
|
||||||
onShowDetails={onShowDetails}
|
|
||||||
getDetails={getDetailsByField}
|
|
||||||
showDetails={openFieldMap.get(field.name) || false}
|
|
||||||
selected={true}
|
|
||||||
useShortDots={useShortDots}
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ul>
|
|
||||||
<div className="euiFlexGroup euiFlexGroup--gutterMedium">
|
|
||||||
<EuiTitle size="xxxs" id="available_fields" className="euiFlexItem">
|
|
||||||
<h3>
|
<h3>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id="kbn.discover.fieldChooser.filter.availableFieldsTitle"
|
id="kbn.discover.fieldChooser.filter.selectedFieldsTitle"
|
||||||
defaultMessage="Available fields"
|
defaultMessage="Selected fields"
|
||||||
/>
|
/>
|
||||||
</h3>
|
</h3>
|
||||||
</EuiTitle>
|
</EuiTitle>
|
||||||
<div className="euiFlexItem euiFlexItem--flexGrowZero">
|
<ul
|
||||||
<EuiButtonIcon
|
className="dscSidebarList dscFieldList--selected"
|
||||||
className={'visible-xs visible-sm dscFieldChooser__toggle'}
|
aria-labelledby="selected_fields"
|
||||||
iconType={showFields ? 'arrowDown' : 'arrowRight'}
|
data-test-subj={`fieldList-selected`}
|
||||||
onClick={() => setShowFields(!showFields)}
|
>
|
||||||
aria-label={
|
{selectedFields.map((field: IndexPatternField, idx: number) => {
|
||||||
showFields
|
return (
|
||||||
? i18n.translate(
|
<li
|
||||||
'kbn.discover.fieldChooser.filter.indexAndFieldsSectionHideAriaLabel',
|
key={`field${idx}`}
|
||||||
{
|
data-attr-field={field.name}
|
||||||
defaultMessage: 'Hide fields',
|
className="dscSidebar__item"
|
||||||
}
|
>
|
||||||
)
|
<DiscoverField
|
||||||
: i18n.translate(
|
field={field}
|
||||||
'kbn.discover.fieldChooser.filter.indexAndFieldsSectionShowAriaLabel',
|
indexPattern={selectedIndexPattern}
|
||||||
{
|
onAddField={onAddField}
|
||||||
defaultMessage: 'Show fields',
|
onRemoveField={onRemoveField}
|
||||||
}
|
onAddFilter={onAddFilter}
|
||||||
)
|
onShowDetails={onShowDetails}
|
||||||
}
|
getDetails={getDetailsByField}
|
||||||
/>
|
showDetails={openFieldMap.get(field.name) || false}
|
||||||
</div>
|
selected={true}
|
||||||
</div>
|
useShortDots={useShortDots}
|
||||||
</>
|
/>
|
||||||
)}
|
</li>
|
||||||
{popularFields.length > 0 && (
|
);
|
||||||
<div>
|
})}
|
||||||
<EuiTitle
|
</ul>
|
||||||
size="xxxs"
|
<div className="euiFlexGroup euiFlexGroup--gutterMedium">
|
||||||
className={`dscFieldListHeader ${!showFields ? 'hidden-sm hidden-xs' : ''}`}
|
<EuiTitle size="xxxs" id="available_fields" className="euiFlexItem">
|
||||||
>
|
<h3>
|
||||||
<h4 style={{ fontWeight: 'normal' }} id="available_fields_popular">
|
<FormattedMessage
|
||||||
<FormattedMessage
|
id="kbn.discover.fieldChooser.filter.availableFieldsTitle"
|
||||||
id="kbn.discover.fieldChooser.filter.popularTitle"
|
defaultMessage="Available fields"
|
||||||
defaultMessage="Popular"
|
|
||||||
/>
|
|
||||||
</h4>
|
|
||||||
</EuiTitle>
|
|
||||||
<ul
|
|
||||||
className={`dscFieldList dscFieldList--popular ${
|
|
||||||
!showFields ? 'hidden-sm hidden-xs' : ''
|
|
||||||
}`}
|
|
||||||
aria-labelledby="available_fields available_fields_popular"
|
|
||||||
data-test-subj={`fieldList-popular`}
|
|
||||||
>
|
|
||||||
{popularFields.map((field: IndexPatternField, idx: number) => {
|
|
||||||
return (
|
|
||||||
<li key={`field${idx}`} data-attr-field={field.name} className="dscSidebar__item">
|
|
||||||
<DiscoverField
|
|
||||||
field={field}
|
|
||||||
indexPattern={selectedIndexPattern}
|
|
||||||
onAddField={onAddField}
|
|
||||||
onRemoveField={onRemoveField}
|
|
||||||
onAddFilter={onAddFilter}
|
|
||||||
onShowDetails={onShowDetails}
|
|
||||||
getDetails={getDetailsByField}
|
|
||||||
showDetails={openFieldMap.get(field.name) || false}
|
|
||||||
useShortDots={useShortDots}
|
|
||||||
/>
|
/>
|
||||||
</li>
|
</h3>
|
||||||
);
|
</EuiTitle>
|
||||||
})}
|
<div className="euiFlexItem euiFlexItem--flexGrowZero">
|
||||||
</ul>
|
<EuiButtonIcon
|
||||||
</div>
|
className={'visible-xs visible-sm dscFieldChooser__toggle'}
|
||||||
)}
|
iconType={showFields ? 'arrowDown' : 'arrowRight'}
|
||||||
|
onClick={() => setShowFields(!showFields)}
|
||||||
|
aria-label={
|
||||||
|
showFields
|
||||||
|
? i18n.translate(
|
||||||
|
'kbn.discover.fieldChooser.filter.indexAndFieldsSectionHideAriaLabel',
|
||||||
|
{
|
||||||
|
defaultMessage: 'Hide fields',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
: i18n.translate(
|
||||||
|
'kbn.discover.fieldChooser.filter.indexAndFieldsSectionShowAriaLabel',
|
||||||
|
{
|
||||||
|
defaultMessage: 'Show fields',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{popularFields.length > 0 && (
|
||||||
|
<div>
|
||||||
|
<EuiTitle
|
||||||
|
size="xxxs"
|
||||||
|
className={`dscFieldListHeader ${!showFields ? 'hidden-sm hidden-xs' : ''}`}
|
||||||
|
>
|
||||||
|
<h4 style={{ fontWeight: 'normal' }} id="available_fields_popular">
|
||||||
|
<FormattedMessage
|
||||||
|
id="kbn.discover.fieldChooser.filter.popularTitle"
|
||||||
|
defaultMessage="Popular"
|
||||||
|
/>
|
||||||
|
</h4>
|
||||||
|
</EuiTitle>
|
||||||
|
<ul
|
||||||
|
className={`dscFieldList dscFieldList--popular ${
|
||||||
|
!showFields ? 'hidden-sm hidden-xs' : ''
|
||||||
|
}`}
|
||||||
|
aria-labelledby="available_fields available_fields_popular"
|
||||||
|
data-test-subj={`fieldList-popular`}
|
||||||
|
>
|
||||||
|
{popularFields.map((field: IndexPatternField, idx: number) => {
|
||||||
|
return (
|
||||||
|
<li
|
||||||
|
key={`field${idx}`}
|
||||||
|
data-attr-field={field.name}
|
||||||
|
className="dscSidebar__item"
|
||||||
|
>
|
||||||
|
<DiscoverField
|
||||||
|
field={field}
|
||||||
|
indexPattern={selectedIndexPattern}
|
||||||
|
onAddField={onAddField}
|
||||||
|
onRemoveField={onRemoveField}
|
||||||
|
onAddFilter={onAddFilter}
|
||||||
|
onShowDetails={onShowDetails}
|
||||||
|
getDetails={getDetailsByField}
|
||||||
|
showDetails={openFieldMap.get(field.name) || false}
|
||||||
|
useShortDots={useShortDots}
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<ul
|
<ul
|
||||||
className={`dscFieldList dscFieldList--unpopular ${
|
className={`dscFieldList dscFieldList--unpopular ${
|
||||||
!showFields ? 'hidden-sm hidden-xs' : ''
|
!showFields ? 'hidden-sm hidden-xs' : ''
|
||||||
}`}
|
}`}
|
||||||
aria-labelledby="available_fields"
|
aria-labelledby="available_fields"
|
||||||
data-test-subj={`fieldList-unpopular`}
|
data-test-subj={`fieldList-unpopular`}
|
||||||
>
|
>
|
||||||
{unpopularFields.map((field: IndexPatternField, idx: number) => {
|
{unpopularFields.map((field: IndexPatternField, idx: number) => {
|
||||||
return (
|
return (
|
||||||
<li key={`field${idx}`} data-attr-field={field.name} className="dscSidebar__item">
|
<li key={`field${idx}`} data-attr-field={field.name} className="dscSidebar__item">
|
||||||
<DiscoverField
|
<DiscoverField
|
||||||
field={field}
|
field={field}
|
||||||
indexPattern={selectedIndexPattern}
|
indexPattern={selectedIndexPattern}
|
||||||
onAddField={onAddField}
|
onAddField={onAddField}
|
||||||
onRemoveField={onRemoveField}
|
onRemoveField={onRemoveField}
|
||||||
onAddFilter={onAddFilter}
|
onAddFilter={onAddFilter}
|
||||||
onShowDetails={onShowDetails}
|
onShowDetails={onShowDetails}
|
||||||
getDetails={getDetailsByField}
|
getDetails={getDetailsByField}
|
||||||
showDetails={openFieldMap.get(field.name) || false}
|
showDetails={openFieldMap.get(field.name) || false}
|
||||||
useShortDots={useShortDots}
|
useShortDots={useShortDots}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
</I18nProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,10 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { wrapInI18nContext } from '../../../kibana_services';
|
|
||||||
import { DiscoverSidebar } from './discover_sidebar';
|
import { DiscoverSidebar } from './discover_sidebar';
|
||||||
|
|
||||||
export function createDiscoverSidebarDirective(reactDirective: any) {
|
export function createDiscoverSidebarDirective(reactDirective: any) {
|
||||||
return reactDirective(wrapInI18nContext(DiscoverSidebar), [
|
return reactDirective(DiscoverSidebar, [
|
||||||
['columns', { watchDepth: 'reference' }],
|
['columns', { watchDepth: 'reference' }],
|
||||||
['fieldCounts', { watchDepth: 'reference' }],
|
['fieldCounts', { watchDepth: 'reference' }],
|
||||||
['hits', { watchDepth: 'reference' }],
|
['hits', { watchDepth: 'reference' }],
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
// Visualize plugin styles
|
// Visualize plugin styles
|
||||||
@import 'np_ready/index';
|
@import 'np_ready/index';
|
||||||
|
|
||||||
|
// should be removed while moving the visualize into NP
|
||||||
|
@import '../../../../../plugins/vis_default_editor/public/index'
|
||||||
|
|
|
@ -36,7 +36,7 @@ import { VisualizationsStart } from '../../../../../plugins/visualizations/publi
|
||||||
import { SavedVisualizations } from './np_ready/types';
|
import { SavedVisualizations } from './np_ready/types';
|
||||||
import { UsageCollectionSetup } from '../../../../../plugins/usage_collection/public';
|
import { UsageCollectionSetup } from '../../../../../plugins/usage_collection/public';
|
||||||
import { KibanaLegacyStart } from '../../../../../plugins/kibana_legacy/public';
|
import { KibanaLegacyStart } from '../../../../../plugins/kibana_legacy/public';
|
||||||
import { DefaultEditorController } from '../../../vis_default_editor/public';
|
import { DefaultEditorController } from '../../../../../plugins/vis_default_editor/public';
|
||||||
|
|
||||||
export interface VisualizeKibanaServices {
|
export interface VisualizeKibanaServices {
|
||||||
pluginInitializerContext: PluginInitializerContext;
|
pluginInitializerContext: PluginInitializerContext;
|
||||||
|
|
|
@ -51,7 +51,7 @@ import {
|
||||||
HomePublicPluginSetup,
|
HomePublicPluginSetup,
|
||||||
} from '../../../../../plugins/home/public';
|
} from '../../../../../plugins/home/public';
|
||||||
import { UsageCollectionSetup } from '../../../../../plugins/usage_collection/public';
|
import { UsageCollectionSetup } from '../../../../../plugins/usage_collection/public';
|
||||||
import { DefaultEditorController } from '../../../vis_default_editor/public';
|
import { DefaultEditorController } from '../../../../../plugins/vis_default_editor/public';
|
||||||
|
|
||||||
export interface VisualizePluginStartDependencies {
|
export interface VisualizePluginStartDependencies {
|
||||||
data: DataPublicPluginStart;
|
data: DataPublicPluginStart;
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import { FileLayerField, VectorLayer, ServiceSettings } from 'ui/vis/map/service_settings';
|
import { FileLayerField, VectorLayer, ServiceSettings } from 'ui/vis/map/service_settings';
|
||||||
import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import { NumberInputOption, SelectOption, SwitchOption } from '../../../vis_type_vislib/public';
|
import { NumberInputOption, SelectOption, SwitchOption } from '../../../vis_type_vislib/public';
|
||||||
import { WmsOptions } from '../../../tile_map/public/components/wms_options';
|
import { WmsOptions } from '../../../tile_map/public/components/wms_options';
|
||||||
import { RegionMapVisParams } from '../types';
|
import { RegionMapVisParams } from '../types';
|
||||||
|
|
|
@ -22,7 +22,7 @@ import { mapToLayerWithId } from './util';
|
||||||
import { createRegionMapVisualization } from './region_map_visualization';
|
import { createRegionMapVisualization } from './region_map_visualization';
|
||||||
import { RegionMapOptions } from './components/region_map_options';
|
import { RegionMapOptions } from './components/region_map_options';
|
||||||
import { truncatedColorSchemas } from '../../../../plugins/charts/public';
|
import { truncatedColorSchemas } from '../../../../plugins/charts/public';
|
||||||
import { Schemas } from '../../vis_default_editor/public';
|
import { Schemas } from '../../../../plugins/vis_default_editor/public';
|
||||||
|
|
||||||
// TODO: reference to TILE_MAP plugin should be removed
|
// TODO: reference to TILE_MAP plugin should be removed
|
||||||
import { ORIGIN } from '../../tile_map/common/origin';
|
import { ORIGIN } from '../../tile_map/common/origin';
|
||||||
|
|
|
@ -164,7 +164,8 @@ export function createRegionMapVisualization({ serviceSettings, $injector, uiSet
|
||||||
}
|
}
|
||||||
|
|
||||||
this._choroplethLayer.on('select', event => {
|
this._choroplethLayer.on('select', event => {
|
||||||
const rowIndex = this._chartData.rows.findIndex(row => row[0] === event);
|
const { rows, columns } = this._chartData;
|
||||||
|
const rowIndex = rows.findIndex(row => row[columns[0].id] === event);
|
||||||
this._vis.API.events.filter({
|
this._vis.API.events.filter({
|
||||||
table: this._chartData,
|
table: this._chartData,
|
||||||
column: 0,
|
column: 0,
|
||||||
|
|
|
@ -21,7 +21,7 @@ import React, { useEffect } from 'react';
|
||||||
import { EuiPanel, EuiSpacer } from '@elastic/eui';
|
import { EuiPanel, EuiSpacer } from '@elastic/eui';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import {
|
import {
|
||||||
BasicOptions,
|
BasicOptions,
|
||||||
RangeOption,
|
RangeOption,
|
||||||
|
|
|
@ -22,7 +22,7 @@ import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
import { convertToGeoJson } from 'ui/vis/map/convert_to_geojson';
|
import { convertToGeoJson } from 'ui/vis/map/convert_to_geojson';
|
||||||
|
|
||||||
import { Schemas } from '../../vis_default_editor/public';
|
import { Schemas } from '../../../../plugins/vis_default_editor/public';
|
||||||
import { createTileMapVisualization } from './tile_map_visualization';
|
import { createTileMapVisualization } from './tile_map_visualization';
|
||||||
import { TileMapOptions } from './components/tile_map_options';
|
import { TileMapOptions } from './components/tile_map_options';
|
||||||
import { MapTypes } from './map_types';
|
import { MapTypes } from './map_types';
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
|
||||||
* license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright
|
|
||||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
|
||||||
* the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
* not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { resolve } from 'path';
|
|
||||||
import { Legacy } from 'kibana';
|
|
||||||
|
|
||||||
import { LegacyPluginApi, LegacyPluginInitializer } from '../../../../src/legacy/types';
|
|
||||||
|
|
||||||
const vidDefaultEditorPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPluginApi) =>
|
|
||||||
new Plugin({
|
|
||||||
id: 'vis_default_editor',
|
|
||||||
require: [],
|
|
||||||
publicDir: resolve(__dirname, 'public'),
|
|
||||||
uiExports: {
|
|
||||||
styleSheetPaths: resolve(__dirname, 'public/index.scss'),
|
|
||||||
},
|
|
||||||
init: (server: Legacy.Server) => ({}),
|
|
||||||
config(Joi: any) {
|
|
||||||
return Joi.object({
|
|
||||||
enabled: Joi.boolean().default(true),
|
|
||||||
}).default();
|
|
||||||
},
|
|
||||||
} as Legacy.PluginSpecOptions);
|
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-default-export
|
|
||||||
export default vidDefaultEditorPluginInitializer;
|
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"name": "vis_default_editor",
|
|
||||||
"version": "kibana"
|
|
||||||
}
|
|
|
@ -30,7 +30,7 @@ import {
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import { MarkdownVisParams } from './types';
|
import { MarkdownVisParams } from './types';
|
||||||
|
|
||||||
function MarkdownOptions({ stateParams, setValue }: VisOptionsProps<MarkdownVisParams>) {
|
function MarkdownOptions({ stateParams, setValue }: VisOptionsProps<MarkdownVisParams>) {
|
||||||
|
|
|
@ -22,7 +22,7 @@ import { i18n } from '@kbn/i18n';
|
||||||
import { MarkdownVisWrapper } from './markdown_vis_controller';
|
import { MarkdownVisWrapper } from './markdown_vis_controller';
|
||||||
import { MarkdownOptions } from './markdown_options';
|
import { MarkdownOptions } from './markdown_options';
|
||||||
import { SettingsOptions } from './settings_options';
|
import { SettingsOptions } from './settings_options';
|
||||||
import { DefaultEditorSize } from '../../vis_default_editor/public';
|
import { DefaultEditorSize } from '../../../../plugins/vis_default_editor/public';
|
||||||
|
|
||||||
export const markdownVisDefinition = {
|
export const markdownVisDefinition = {
|
||||||
name: 'markdown',
|
name: 'markdown',
|
||||||
|
|
|
@ -21,7 +21,7 @@ import React from 'react';
|
||||||
import { EuiPanel } from '@elastic/eui';
|
import { EuiPanel } from '@elastic/eui';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import { RangeOption, SwitchOption } from '../../vis_type_vislib/public';
|
import { RangeOption, SwitchOption } from '../../vis_type_vislib/public';
|
||||||
import { MarkdownVisParams } from './types';
|
import { MarkdownVisParams } from './types';
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ import {
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import {
|
import {
|
||||||
ColorModes,
|
ColorModes,
|
||||||
ColorRanges,
|
ColorRanges,
|
||||||
|
|
|
@ -23,10 +23,6 @@ import { functionWrapper } from '../../../../plugins/expressions/common/expressi
|
||||||
|
|
||||||
jest.mock('ui/new_platform');
|
jest.mock('ui/new_platform');
|
||||||
|
|
||||||
jest.mock('../../vis_default_editor/public', () => ({
|
|
||||||
Schemas: class {},
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('interpreter/functions#metric', () => {
|
describe('interpreter/functions#metric', () => {
|
||||||
const fn = functionWrapper(createMetricVisFn());
|
const fn = functionWrapper(createMetricVisFn());
|
||||||
const context = {
|
const context = {
|
||||||
|
|
|
@ -22,10 +22,6 @@ import { MetricVisComponent } from './components/metric_vis_component';
|
||||||
|
|
||||||
jest.mock('ui/new_platform');
|
jest.mock('ui/new_platform');
|
||||||
|
|
||||||
jest.mock('../../vis_default_editor/public', () => ({
|
|
||||||
Schemas: class {},
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('metric_vis - createMetricVisTypeDefinition', () => {
|
describe('metric_vis - createMetricVisTypeDefinition', () => {
|
||||||
it('has metric vis component set', () => {
|
it('has metric vis component set', () => {
|
||||||
const def = createMetricVisTypeDefinition();
|
const def = createMetricVisTypeDefinition();
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { MetricVisOptions } from './components/metric_vis_options';
|
||||||
import { ColorModes } from '../../vis_type_vislib/public';
|
import { ColorModes } from '../../vis_type_vislib/public';
|
||||||
import { ColorSchemas, colorSchemas } from '../../../../plugins/charts/public';
|
import { ColorSchemas, colorSchemas } from '../../../../plugins/charts/public';
|
||||||
import { AggGroupNames } from '../../../../plugins/data/public';
|
import { AggGroupNames } from '../../../../plugins/data/public';
|
||||||
import { Schemas } from '../../vis_default_editor/public';
|
import { Schemas } from '../../../../plugins/vis_default_editor/public';
|
||||||
|
|
||||||
export const createMetricVisTypeDefinition = () => ({
|
export const createMetricVisTypeDefinition = () => ({
|
||||||
name: 'metric',
|
name: 'metric',
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { EuiIconTip, EuiPanel } from '@elastic/eui';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import { search } from '../../../../../plugins/data/public';
|
import { search } from '../../../../../plugins/data/public';
|
||||||
import { NumberInputOption, SwitchOption, SelectOption } from '../../../vis_type_vislib/public';
|
import { NumberInputOption, SwitchOption, SelectOption } from '../../../vis_type_vislib/public';
|
||||||
import { TableVisParams } from '../types';
|
import { TableVisParams } from '../types';
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { AggGroupNames } from '../../../../plugins/data/public';
|
import { AggGroupNames } from '../../../../plugins/data/public';
|
||||||
import { Schemas } from '../../vis_default_editor/public';
|
import { Schemas } from '../../../../plugins/vis_default_editor/public';
|
||||||
import { Vis } from '../../../../plugins/visualizations/public';
|
import { Vis } from '../../../../plugins/visualizations/public';
|
||||||
import { tableVisResponseHandler } from './table_vis_response_handler';
|
import { tableVisResponseHandler } from './table_vis_response_handler';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { EuiPanel } from '@elastic/eui';
|
import { EuiPanel } from '@elastic/eui';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import { ValidatedDualRange } from '../../../../../../src/plugins/kibana_react/public';
|
import { ValidatedDualRange } from '../../../../../../src/plugins/kibana_react/public';
|
||||||
import { VisOptionsProps } from '../../../vis_default_editor/public';
|
|
||||||
import { SelectOption, SwitchOption } from '../../../vis_type_vislib/public';
|
import { SelectOption, SwitchOption } from '../../../vis_type_vislib/public';
|
||||||
import { TagCloudVisParams } from '../types';
|
import { TagCloudVisParams } from '../types';
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
import { Schemas } from '../../vis_default_editor/public';
|
import { Schemas } from '../../../../plugins/vis_default_editor/public';
|
||||||
|
|
||||||
import { TagCloudOptions } from './components/tag_cloud_options';
|
import { TagCloudOptions } from './components/tag_cloud_options';
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
import { search } from '../../../../../plugins/data/public';
|
import { search } from '../../../../../plugins/data/public';
|
||||||
const { isValidEsInterval } = search.aggs;
|
const { isValidEsInterval } = search.aggs;
|
||||||
import { useValidation } from '../../../vis_default_editor/public';
|
import { useValidation } from '../../../../../plugins/vis_default_editor/public';
|
||||||
|
|
||||||
const intervalOptions = [
|
const intervalOptions = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { EuiPanel } from '@elastic/eui';
|
import { EuiPanel } from '@elastic/eui';
|
||||||
|
|
||||||
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import { VisParams } from './timelion_vis_fn';
|
import { VisParams } from './timelion_vis_fn';
|
||||||
import { TimelionInterval, TimelionExpressionInput } from './components';
|
import { TimelionInterval, TimelionExpressionInput } from './components';
|
||||||
import { VisOptionsProps } from '../../vis_default_editor/public';
|
|
||||||
|
|
||||||
function TimelionOptions({ stateParams, setValue, setValidity }: VisOptionsProps<VisParams>) {
|
function TimelionOptions({ stateParams, setValue, setValidity }: VisOptionsProps<VisParams>) {
|
||||||
const setInterval = useCallback((value: VisParams['interval']) => setValue('interval', value), [
|
const setInterval = useCallback((value: VisParams['interval']) => setValue('interval', value), [
|
||||||
|
|
|
@ -21,7 +21,7 @@ import React from 'react';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
import { KibanaContextProvider } from '../../../../plugins/kibana_react/public';
|
import { KibanaContextProvider } from '../../../../plugins/kibana_react/public';
|
||||||
import { DefaultEditorSize } from '../../vis_default_editor/public';
|
import { DefaultEditorSize } from '../../../../plugins/vis_default_editor/public';
|
||||||
import { getTimelionRequestHandler } from './helpers/timelion_request_handler';
|
import { getTimelionRequestHandler } from './helpers/timelion_request_handler';
|
||||||
import { TimelionVisComponent, TimelionVisComponentProp } from './components';
|
import { TimelionVisComponent, TimelionVisComponentProp } from './components';
|
||||||
import { TimelionOptions } from './timelion_options';
|
import { TimelionOptions } from './timelion_options';
|
||||||
|
|
|
@ -24,11 +24,11 @@ import compactStringify from 'json-stringify-pretty-compact';
|
||||||
import hjson from 'hjson';
|
import hjson from 'hjson';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import { getNotifications } from '../services';
|
import { getNotifications } from '../services';
|
||||||
import { VisParams } from '../vega_fn';
|
import { VisParams } from '../vega_fn';
|
||||||
import { VegaHelpMenu } from './vega_help_menu';
|
import { VegaHelpMenu } from './vega_help_menu';
|
||||||
import { VegaActionsMenu } from './vega_actions_menu';
|
import { VegaActionsMenu } from './vega_actions_menu';
|
||||||
import { VisOptionsProps } from '../../../vis_default_editor/public';
|
|
||||||
|
|
||||||
const aceOptions = {
|
const aceOptions = {
|
||||||
maxLines: Infinity,
|
maxLines: Infinity,
|
||||||
|
|
|
@ -18,8 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
// @ts-ignore
|
import { DefaultEditorSize } from '../../../../plugins/vis_default_editor/public';
|
||||||
import { DefaultEditorSize } from '../../vis_default_editor/public';
|
|
||||||
import { VegaVisualizationDependencies } from './plugin';
|
import { VegaVisualizationDependencies } from './plugin';
|
||||||
import { VegaVisEditor } from './components';
|
import { VegaVisEditor } from './components';
|
||||||
import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/common';
|
import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/common';
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { palettes } from '@elastic/eui/lib/services';
|
||||||
import { euiPaletteColorBlind } from '@elastic/eui/lib/services';
|
import { euiPaletteColorBlind } from '@elastic/eui/lib/services';
|
||||||
|
|
||||||
import { AggGroupNames } from '../../../../plugins/data/public';
|
import { AggGroupNames } from '../../../../plugins/data/public';
|
||||||
import { Schemas } from '../../vis_default_editor/public';
|
import { Schemas } from '../../../../plugins/vis_default_editor/public';
|
||||||
import {
|
import {
|
||||||
Positions,
|
Positions,
|
||||||
ChartTypes,
|
ChartTypes,
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
import { VisOptionsProps } from '../../../../vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import { SwitchOption } from './switch';
|
import { SwitchOption } from './switch';
|
||||||
import { SelectOption } from './select';
|
import { SelectOption } from './select';
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,10 @@ import { last } from 'lodash';
|
||||||
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
import { RangeValues, RangesParamEditor } from '../../../../vis_default_editor/public';
|
import {
|
||||||
|
RangeValues,
|
||||||
|
RangesParamEditor,
|
||||||
|
} from '../../../../../../plugins/vis_default_editor/public';
|
||||||
|
|
||||||
export type SetColorRangeValue = (paramName: string, value: RangeValues[]) => void;
|
export type SetColorRangeValue = (paramName: string, value: RangeValues[]) => void;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ import { i18n } from '@kbn/i18n';
|
||||||
import { EuiLink, EuiText } from '@elastic/eui';
|
import { EuiLink, EuiText } from '@elastic/eui';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import { VisOptionsProps } from '../../../../vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import { SelectOption } from './select';
|
import { SelectOption } from './select';
|
||||||
import { SwitchOption } from './switch';
|
import { SwitchOption } from './switch';
|
||||||
import { ColorSchemaVislibParams } from '../../types';
|
import { ColorSchemaVislibParams } from '../../types';
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
import React, { useEffect, useState, useCallback } from 'react';
|
import React, { useEffect, useState, useCallback } from 'react';
|
||||||
|
|
||||||
import { VisOptionsProps } from '../../../../vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
|
|
||||||
export interface ValidationVisOptionsProps<T> extends VisOptionsProps<T> {
|
export interface ValidationVisOptionsProps<T> extends VisOptionsProps<T> {
|
||||||
setMultipleValidity(paramName: string, isValid: boolean): void;
|
setMultipleValidity(paramName: string, isValid: boolean): void;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { EuiSpacer } from '@elastic/eui';
|
import { EuiSpacer } from '@elastic/eui';
|
||||||
|
|
||||||
import { VisOptionsProps } from '../../../../../vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import { GaugeVisParams } from '../../../gauge';
|
import { GaugeVisParams } from '../../../gauge';
|
||||||
import { RangesPanel } from './ranges_panel';
|
import { RangesPanel } from './ranges_panel';
|
||||||
import { StylePanel } from './style_panel';
|
import { StylePanel } from './style_panel';
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import { VisOptionsProps } from '../../../../../vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import {
|
import {
|
||||||
BasicOptions,
|
BasicOptions,
|
||||||
ColorRanges,
|
ColorRanges,
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { EuiColorPicker, EuiFormRow, EuiPanel, EuiSpacer, EuiTitle } from '@elas
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import { VisOptionsProps } from '../../../../../vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import { ValueAxis } from '../../../types';
|
import { ValueAxis } from '../../../types';
|
||||||
import { HeatmapVisParams } from '../../../heatmap';
|
import { HeatmapVisParams } from '../../../heatmap';
|
||||||
import { SwitchOption } from '../../common';
|
import { SwitchOption } from '../../common';
|
||||||
|
|
|
@ -54,6 +54,7 @@ exports[`MetricsAxisOptions component should init with the default set of props
|
||||||
}
|
}
|
||||||
vis={
|
vis={
|
||||||
Object {
|
Object {
|
||||||
|
"serialize": [MockFunction],
|
||||||
"setState": [MockFunction],
|
"setState": [MockFunction],
|
||||||
"type": Object {
|
"type": Object {
|
||||||
"schemas": Object {
|
"schemas": Object {
|
||||||
|
@ -126,6 +127,7 @@ exports[`MetricsAxisOptions component should init with the default set of props
|
||||||
}
|
}
|
||||||
vis={
|
vis={
|
||||||
Object {
|
Object {
|
||||||
|
"serialize": [MockFunction],
|
||||||
"setState": [MockFunction],
|
"setState": [MockFunction],
|
||||||
"type": Object {
|
"type": Object {
|
||||||
"schemas": Object {
|
"schemas": Object {
|
||||||
|
@ -169,6 +171,7 @@ exports[`MetricsAxisOptions component should init with the default set of props
|
||||||
setCategoryAxis={[Function]}
|
setCategoryAxis={[Function]}
|
||||||
vis={
|
vis={
|
||||||
Object {
|
Object {
|
||||||
|
"serialize": [MockFunction],
|
||||||
"setState": [MockFunction],
|
"setState": [MockFunction],
|
||||||
"type": Object {
|
"type": Object {
|
||||||
"schemas": Object {
|
"schemas": Object {
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import { Axis } from '../../../types';
|
import { Axis } from '../../../types';
|
||||||
import { SelectOption, SwitchOption } from '../../common';
|
import { SelectOption, SwitchOption } from '../../common';
|
||||||
import { LabelOptions, SetAxisLabel } from './label_options';
|
import { LabelOptions, SetAxisLabel } from './label_options';
|
||||||
|
|
|
@ -95,6 +95,7 @@ describe('MetricsAxisOptions component', () => {
|
||||||
schemas: { metrics: [{ name: 'metric' }] },
|
schemas: { metrics: [{ name: 'metric' }] },
|
||||||
},
|
},
|
||||||
setState: jest.fn(),
|
setState: jest.fn(),
|
||||||
|
serialize: jest.fn(),
|
||||||
},
|
},
|
||||||
stateParams: {
|
stateParams: {
|
||||||
valueAxes: [axis],
|
valueAxes: [axis],
|
||||||
|
|
|
@ -299,7 +299,7 @@ function MetricsAxisOptions(props: ValidationVisOptionsProps<BasicVislibParams>)
|
||||||
}, [stateParams.seriesParams]);
|
}, [stateParams.seriesParams]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
vis.setState({ type: visType } as any);
|
vis.setState({ ...vis.serialize(), type: visType });
|
||||||
}, [vis, visType]);
|
}, [vis, visType]);
|
||||||
|
|
||||||
return isTabSelected ? (
|
return isTabSelected ? (
|
||||||
|
|
|
@ -22,7 +22,7 @@ import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import { VisOptionsProps } from '../../../../vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import { BasicOptions, TruncateLabelsOption, SwitchOption } from '../common';
|
import { BasicOptions, TruncateLabelsOption, SwitchOption } from '../common';
|
||||||
import { PieVisParams } from '../../pie';
|
import { PieVisParams } from '../../pie';
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import { VisOptionsProps } from '../../../../../vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import { SelectOption, SwitchOption } from '../../common';
|
import { SelectOption, SwitchOption } from '../../common';
|
||||||
import { BasicVislibParams, ValueAxis } from '../../../types';
|
import { BasicVislibParams, ValueAxis } from '../../../types';
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
import { RangeValues, Schemas } from '../../vis_default_editor/public';
|
import { RangeValues, Schemas } from '../../../../plugins/vis_default_editor/public';
|
||||||
import { AggGroupNames } from '../../../../plugins/data/public';
|
import { AggGroupNames } from '../../../../plugins/data/public';
|
||||||
import { GaugeOptions } from './components/options';
|
import { GaugeOptions } from './components/options';
|
||||||
import { getGaugeCollections, Alignments, ColorModes, GaugeTypes } from './utils/collections';
|
import { getGaugeCollections, Alignments, ColorModes, GaugeTypes } from './utils/collections';
|
||||||
|
|
|
@ -25,7 +25,7 @@ import { createVislibVisController } from './vis_controller';
|
||||||
import { VisTypeVislibDependencies } from './plugin';
|
import { VisTypeVislibDependencies } from './plugin';
|
||||||
import { ColorSchemas } from '../../../../plugins/charts/public';
|
import { ColorSchemas } from '../../../../plugins/charts/public';
|
||||||
import { AggGroupNames } from '../../../../plugins/data/public';
|
import { AggGroupNames } from '../../../../plugins/data/public';
|
||||||
import { Schemas } from '../../vis_default_editor/public';
|
import { Schemas } from '../../../../plugins/vis_default_editor/public';
|
||||||
|
|
||||||
export const createGoalVisTypeDefinition = (deps: VisTypeVislibDependencies) => ({
|
export const createGoalVisTypeDefinition = (deps: VisTypeVislibDependencies) => ({
|
||||||
name: 'goal',
|
name: 'goal',
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
import { RangeValues, Schemas } from '../../vis_default_editor/public';
|
import { RangeValues, Schemas } from '../../../../plugins/vis_default_editor/public';
|
||||||
import { AggGroupNames } from '../../../../plugins/data/public';
|
import { AggGroupNames } from '../../../../plugins/data/public';
|
||||||
import { AxisTypes, getHeatmapCollections, Positions, ScaleTypes } from './utils/collections';
|
import { AxisTypes, getHeatmapCollections, Positions, ScaleTypes } from './utils/collections';
|
||||||
import { HeatmapOptions } from './components/options';
|
import { HeatmapOptions } from './components/options';
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { palettes } from '@elastic/eui/lib/services';
|
||||||
import { euiPaletteColorBlind } from '@elastic/eui/lib/services';
|
import { euiPaletteColorBlind } from '@elastic/eui/lib/services';
|
||||||
|
|
||||||
import { AggGroupNames } from '../../../../plugins/data/public';
|
import { AggGroupNames } from '../../../../plugins/data/public';
|
||||||
import { Schemas } from '../../vis_default_editor/public';
|
import { Schemas } from '../../../../plugins/vis_default_editor/public';
|
||||||
import {
|
import {
|
||||||
Positions,
|
Positions,
|
||||||
ChartTypes,
|
ChartTypes,
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { palettes } from '@elastic/eui/lib/services';
|
||||||
import { euiPaletteColorBlind } from '@elastic/eui/lib/services';
|
import { euiPaletteColorBlind } from '@elastic/eui/lib/services';
|
||||||
|
|
||||||
import { AggGroupNames } from '../../../../plugins/data/public';
|
import { AggGroupNames } from '../../../../plugins/data/public';
|
||||||
import { Schemas } from '../../vis_default_editor/public';
|
import { Schemas } from '../../../../plugins/vis_default_editor/public';
|
||||||
import {
|
import {
|
||||||
Positions,
|
Positions,
|
||||||
ChartTypes,
|
ChartTypes,
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { palettes } from '@elastic/eui/lib/services';
|
||||||
import { euiPaletteColorBlind } from '@elastic/eui/lib/services';
|
import { euiPaletteColorBlind } from '@elastic/eui/lib/services';
|
||||||
|
|
||||||
import { AggGroupNames } from '../../../../plugins/data/public';
|
import { AggGroupNames } from '../../../../plugins/data/public';
|
||||||
import { Schemas } from '../../vis_default_editor/public';
|
import { Schemas } from '../../../../plugins/vis_default_editor/public';
|
||||||
import {
|
import {
|
||||||
Positions,
|
Positions,
|
||||||
ChartTypes,
|
ChartTypes,
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
import { AggGroupNames } from '../../../../plugins/data/public';
|
import { AggGroupNames } from '../../../../plugins/data/public';
|
||||||
import { Schemas } from '../../vis_default_editor/public';
|
import { Schemas } from '../../../../plugins/vis_default_editor/public';
|
||||||
import { PieOptions } from './components/options';
|
import { PieOptions } from './components/options';
|
||||||
import { getPositions, Positions } from './utils/collections';
|
import { getPositions, Positions } from './utils/collections';
|
||||||
import { createVislibVisController } from './vis_controller';
|
import { createVislibVisController } from './vis_controller';
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
import { VisOptionsProps } from '../../../vis_default_editor/public';
|
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
|
||||||
import { PointSeriesOptions, MetricsAxisOptions } from '../components/options';
|
import { PointSeriesOptions, MetricsAxisOptions } from '../components/options';
|
||||||
import { ValidationWrapper } from '../components/common';
|
import { ValidationWrapper } from '../components/common';
|
||||||
import { BasicVislibParams } from '../types';
|
import { BasicVislibParams } from '../types';
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
|
||||||
* license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright
|
|
||||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
|
||||||
* the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
* not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { KIBANA_STATS_TYPE } from '../constants';
|
|
||||||
import { getKibanaInfoForStats } from '../lib';
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize a collector for Kibana Ops Stats
|
|
||||||
*
|
|
||||||
* NOTE this collector's fetch method returns the latest stats from the
|
|
||||||
* Hapi/Good/Even-Better ops event listener. Therefore, the stats reset
|
|
||||||
* every 5 seconds (the default value of the ops.interval configuration
|
|
||||||
* setting). That makes it geared for providing the latest "real-time"
|
|
||||||
* stats. In the long-term, fetch should return stats that constantly
|
|
||||||
* accumulate over the server's uptime for better machine readability.
|
|
||||||
* Since the data is captured, timestamped and stored, the historical
|
|
||||||
* data can provide "real-time" stats by calculating a derivative of
|
|
||||||
* the metrics.
|
|
||||||
* See PR comment in https://github.com/elastic/kibana/pull/20577/files#r202416647
|
|
||||||
*/
|
|
||||||
export function getOpsStatsCollector(usageCollection, server, kbnServer) {
|
|
||||||
return usageCollection.makeStatsCollector({
|
|
||||||
type: KIBANA_STATS_TYPE,
|
|
||||||
fetch: () => {
|
|
||||||
return {
|
|
||||||
kibana: getKibanaInfoForStats(server, kbnServer),
|
|
||||||
...kbnServer.metrics, // latest metrics captured from the ops event listener in src/legacy/server/status/index
|
|
||||||
};
|
|
||||||
},
|
|
||||||
isReady: () => true,
|
|
||||||
ignoreForInternalUploader: true, // Ignore this one from internal uploader. A different stats collector is used there.
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function registerOpsStatsCollector(usageCollection, server, kbnServer) {
|
|
||||||
if (usageCollection) {
|
|
||||||
const collector = getOpsStatsCollector(usageCollection, server, kbnServer);
|
|
||||||
usageCollection.registerCollector(collector);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -20,7 +20,6 @@
|
||||||
import ServerStatus from './server_status';
|
import ServerStatus from './server_status';
|
||||||
import { Metrics } from './lib/metrics';
|
import { Metrics } from './lib/metrics';
|
||||||
import { registerStatusPage, registerStatusApi, registerStatsApi } from './routes';
|
import { registerStatusPage, registerStatusApi, registerStatsApi } from './routes';
|
||||||
import { registerOpsStatsCollector } from './collectors';
|
|
||||||
import Oppsy from 'oppsy';
|
import Oppsy from 'oppsy';
|
||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import { getOSInfo } from './lib/get_os_info';
|
import { getOSInfo } from './lib/get_os_info';
|
||||||
|
@ -28,7 +27,6 @@ import { getOSInfo } from './lib/get_os_info';
|
||||||
export function statusMixin(kbnServer, server, config) {
|
export function statusMixin(kbnServer, server, config) {
|
||||||
kbnServer.status = new ServerStatus(kbnServer.server);
|
kbnServer.status = new ServerStatus(kbnServer.server);
|
||||||
const { usageCollection } = server.newPlatform.setup.plugins;
|
const { usageCollection } = server.newPlatform.setup.plugins;
|
||||||
registerOpsStatsCollector(usageCollection, server, kbnServer);
|
|
||||||
|
|
||||||
const metrics = new Metrics(config, server);
|
const metrics = new Metrics(config, server);
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,6 @@ import React from 'react';
|
||||||
import { ErrorEmbeddable } from './error_embeddable';
|
import { ErrorEmbeddable } from './error_embeddable';
|
||||||
import { EmbeddableRoot } from './embeddable_root';
|
import { EmbeddableRoot } from './embeddable_root';
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
// @ts-ignore
|
|
||||||
import { findTestSubject } from '@elastic/eui/lib/test';
|
|
||||||
|
|
||||||
test('ErrorEmbeddable renders an embeddable', async () => {
|
test('ErrorEmbeddable renders an embeddable', async () => {
|
||||||
const embeddable = new ErrorEmbeddable('some error occurred', { id: '123', title: 'Error' });
|
const embeddable = new ErrorEmbeddable('some error occurred', { id: '123', title: 'Error' });
|
||||||
|
|
|
@ -80,3 +80,14 @@ export const APPLICATION_USAGE_TYPE = 'application_usage';
|
||||||
* The type name used within the Monitoring index to publish management stats.
|
* The type name used within the Monitoring index to publish management stats.
|
||||||
*/
|
*/
|
||||||
export const KIBANA_STACK_MANAGEMENT_STATS_TYPE = 'stack_management';
|
export const KIBANA_STACK_MANAGEMENT_STATS_TYPE = 'stack_management';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type name used to publish Kibana usage stats.
|
||||||
|
* NOTE: this string shows as-is in the stats API as a field name for the kibana usage stats
|
||||||
|
*/
|
||||||
|
export const KIBANA_USAGE_TYPE = 'kibana';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type name used to publish Kibana usage stats in the formatted as bulk.
|
||||||
|
*/
|
||||||
|
export const KIBANA_STATS_TYPE = 'kibana_stats';
|
||||||
|
|
|
@ -22,3 +22,5 @@ export { registerUiMetricUsageCollector } from './ui_metric';
|
||||||
export { registerTelemetryPluginUsageCollector } from './telemetry_plugin';
|
export { registerTelemetryPluginUsageCollector } from './telemetry_plugin';
|
||||||
export { registerManagementUsageCollector } from './management';
|
export { registerManagementUsageCollector } from './management';
|
||||||
export { registerApplicationUsageCollector } from './application_usage';
|
export { registerApplicationUsageCollector } from './application_usage';
|
||||||
|
export { registerKibanaUsageCollector } from './kibana';
|
||||||
|
export { registerOpsStatsCollector } from './ops_stats';
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* 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 { getSavedObjectsCounts } from './get_saved_object_counts';
|
||||||
|
|
||||||
|
describe('getSavedObjectsCounts', () => {
|
||||||
|
test('Get all the saved objects equal to 0 because no results were found', async () => {
|
||||||
|
const callCluster = jest.fn(() => ({}));
|
||||||
|
|
||||||
|
const results = await getSavedObjectsCounts(callCluster as any, '.kibana');
|
||||||
|
expect(results).toStrictEqual({
|
||||||
|
dashboard: { total: 0 },
|
||||||
|
visualization: { total: 0 },
|
||||||
|
search: { total: 0 },
|
||||||
|
index_pattern: { total: 0 },
|
||||||
|
graph_workspace: { total: 0 },
|
||||||
|
timelion_sheet: { total: 0 },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Merge the zeros with the results', async () => {
|
||||||
|
const callCluster = jest.fn(() => ({
|
||||||
|
aggregations: {
|
||||||
|
types: {
|
||||||
|
buckets: [
|
||||||
|
{ key: 'dashboard', doc_count: 1 },
|
||||||
|
{ key: 'timelion-sheet', doc_count: 2 },
|
||||||
|
{ key: 'index-pattern', value: 2 }, // Malformed on purpose
|
||||||
|
{ key: 'graph_workspace', doc_count: 3 }, // already snake_cased
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const results = await getSavedObjectsCounts(callCluster as any, '.kibana');
|
||||||
|
expect(results).toStrictEqual({
|
||||||
|
dashboard: { total: 1 },
|
||||||
|
visualization: { total: 0 },
|
||||||
|
search: { total: 0 },
|
||||||
|
index_pattern: { total: 0 },
|
||||||
|
graph_workspace: { total: 3 },
|
||||||
|
timelion_sheet: { total: 2 },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moved from /x-pack/plugins/monitoring/server/kibana_monitoring/collectors/get_kibana_usage_collector.ts
|
||||||
|
*
|
||||||
|
* The PR https://github.com/elastic/kibana/pull/62665 proved what the issue https://github.com/elastic/kibana/issues/58249
|
||||||
|
* was claiming: the structure and payload for common telemetry bits differs between Monitoring and OSS/X-Pack collections.
|
||||||
|
*
|
||||||
|
* Unifying this logic from Monitoring that makes sense to have in OSS here and we will import it on the monitoring side to reuse it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { snakeCase } from 'lodash';
|
||||||
|
import { APICaller } from 'kibana/server';
|
||||||
|
|
||||||
|
const TYPES = [
|
||||||
|
'dashboard',
|
||||||
|
'visualization',
|
||||||
|
'search',
|
||||||
|
'index-pattern',
|
||||||
|
'graph-workspace',
|
||||||
|
'timelion-sheet',
|
||||||
|
];
|
||||||
|
|
||||||
|
export interface KibanaSavedObjectCounts {
|
||||||
|
[pluginName: string]: {
|
||||||
|
total: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getSavedObjectsCounts(
|
||||||
|
callCluster: APICaller,
|
||||||
|
kibanaIndex: string // Typically '.kibana'. We might need a way to obtain it from the SavedObjects client (or the SavedObjects client to provide a way to run aggregations?)
|
||||||
|
): Promise<KibanaSavedObjectCounts> {
|
||||||
|
const savedObjectCountSearchParams = {
|
||||||
|
index: kibanaIndex,
|
||||||
|
ignoreUnavailable: true,
|
||||||
|
filterPath: 'aggregations.types.buckets',
|
||||||
|
body: {
|
||||||
|
size: 0,
|
||||||
|
query: {
|
||||||
|
terms: { type: TYPES },
|
||||||
|
},
|
||||||
|
aggs: {
|
||||||
|
types: {
|
||||||
|
terms: { field: 'type', size: TYPES.length },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const resp = await callCluster('search', savedObjectCountSearchParams);
|
||||||
|
const buckets: Array<{ key: string; doc_count: number }> =
|
||||||
|
resp.aggregations?.types?.buckets || [];
|
||||||
|
|
||||||
|
// Initialise the object with all zeros for all the types
|
||||||
|
const allZeros: KibanaSavedObjectCounts = TYPES.reduce(
|
||||||
|
(acc, type) => ({ ...acc, [snakeCase(type)]: { total: 0 } }),
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add the doc_count from each bucket
|
||||||
|
return buckets.reduce(
|
||||||
|
(acc, { key, doc_count: total }) => (total ? { ...acc, [snakeCase(key)]: { total } } : acc),
|
||||||
|
allZeros
|
||||||
|
);
|
||||||
|
}
|
76
src/plugins/telemetry/server/collectors/kibana/index.test.ts
Normal file
76
src/plugins/telemetry/server/collectors/kibana/index.test.ts
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* 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 { UsageCollectionSetup } from '../../../../../plugins/usage_collection/server';
|
||||||
|
import { pluginInitializerContextConfigMock } from '../../../../../core/server/mocks';
|
||||||
|
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||||
|
import { CollectorOptions } from '../../../../../plugins/usage_collection/server/collector/collector';
|
||||||
|
|
||||||
|
import { registerKibanaUsageCollector } from './';
|
||||||
|
|
||||||
|
describe('telemetry_kibana', () => {
|
||||||
|
let collector: CollectorOptions;
|
||||||
|
|
||||||
|
const usageCollectionMock: jest.Mocked<UsageCollectionSetup> = {
|
||||||
|
makeUsageCollector: jest.fn().mockImplementation(config => (collector = config)),
|
||||||
|
registerCollector: jest.fn(),
|
||||||
|
} as any;
|
||||||
|
|
||||||
|
const legacyConfig$ = pluginInitializerContextConfigMock({}).legacy.globalConfig$;
|
||||||
|
const callCluster = jest.fn().mockImplementation(() => ({}));
|
||||||
|
|
||||||
|
beforeAll(() => registerKibanaUsageCollector(usageCollectionMock, legacyConfig$));
|
||||||
|
afterAll(() => jest.clearAllTimers());
|
||||||
|
|
||||||
|
test('registered collector is set', () => {
|
||||||
|
expect(collector).not.toBeUndefined();
|
||||||
|
expect(collector.type).toBe('kibana');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('fetch', async () => {
|
||||||
|
expect(await collector.fetch(callCluster)).toStrictEqual({
|
||||||
|
index: '.kibana-tests',
|
||||||
|
dashboard: { total: 0 },
|
||||||
|
visualization: { total: 0 },
|
||||||
|
search: { total: 0 },
|
||||||
|
index_pattern: { total: 0 },
|
||||||
|
graph_workspace: { total: 0 },
|
||||||
|
timelion_sheet: { total: 0 },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('formatForBulkUpload', async () => {
|
||||||
|
const resultFromFetch = {
|
||||||
|
index: '.kibana-tests',
|
||||||
|
dashboard: { total: 0 },
|
||||||
|
visualization: { total: 0 },
|
||||||
|
search: { total: 0 },
|
||||||
|
index_pattern: { total: 0 },
|
||||||
|
graph_workspace: { total: 0 },
|
||||||
|
timelion_sheet: { total: 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(collector.formatForBulkUpload!(resultFromFetch)).toStrictEqual({
|
||||||
|
type: 'kibana_stats',
|
||||||
|
payload: {
|
||||||
|
usage: resultFromFetch,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -17,4 +17,4 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const KIBANA_STATS_TYPE = 'oss_kibana_stats'; // kibana stats per 5s intervals
|
export { registerKibanaUsageCollector } from './kibana_usage_collector';
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* 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 { Observable } from 'rxjs';
|
||||||
|
import { take } from 'rxjs/operators';
|
||||||
|
import { SharedGlobalConfig } from 'kibana/server';
|
||||||
|
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
|
||||||
|
import { KIBANA_STATS_TYPE, KIBANA_USAGE_TYPE } from '../../../common/constants';
|
||||||
|
import { getSavedObjectsCounts } from './get_saved_object_counts';
|
||||||
|
|
||||||
|
export function getKibanaUsageCollector(
|
||||||
|
usageCollection: UsageCollectionSetup,
|
||||||
|
legacyConfig$: Observable<SharedGlobalConfig>
|
||||||
|
) {
|
||||||
|
return usageCollection.makeUsageCollector({
|
||||||
|
type: KIBANA_USAGE_TYPE,
|
||||||
|
isReady: () => true,
|
||||||
|
async fetch(callCluster) {
|
||||||
|
const {
|
||||||
|
kibana: { index },
|
||||||
|
} = await legacyConfig$.pipe(take(1)).toPromise();
|
||||||
|
return {
|
||||||
|
index,
|
||||||
|
...(await getSavedObjectsCounts(callCluster, index)),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Format the response data into a model for internal upload
|
||||||
|
* 1. Make this data part of the "kibana_stats" type
|
||||||
|
* 2. Organize the payload in the usage namespace of the data payload (usage.index, etc)
|
||||||
|
*/
|
||||||
|
formatForBulkUpload: result => {
|
||||||
|
return {
|
||||||
|
type: KIBANA_STATS_TYPE,
|
||||||
|
payload: {
|
||||||
|
usage: result,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function registerKibanaUsageCollector(
|
||||||
|
usageCollection: UsageCollectionSetup,
|
||||||
|
legacyConfig$: Observable<SharedGlobalConfig>
|
||||||
|
) {
|
||||||
|
usageCollection.registerCollector(getKibanaUsageCollector(usageCollection, legacyConfig$));
|
||||||
|
}
|
43
src/plugins/telemetry/server/collectors/ops_stats/__snapshots__/index.test.ts.snap
generated
Normal file
43
src/plugins/telemetry/server/collectors/ops_stats/__snapshots__/index.test.ts.snap
generated
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`telemetry_ops_stats should return something when there is a metric 1`] = `
|
||||||
|
Object {
|
||||||
|
"concurrent_connections": 20,
|
||||||
|
"os": Object {
|
||||||
|
"load": Object {
|
||||||
|
"15m": 3,
|
||||||
|
"1m": 0.5,
|
||||||
|
"5m": 1,
|
||||||
|
},
|
||||||
|
"memory": Object {
|
||||||
|
"free_in_bytes": 10,
|
||||||
|
"total_in_bytes": 10,
|
||||||
|
"used_in_bytes": 10,
|
||||||
|
},
|
||||||
|
"platform": "darwin",
|
||||||
|
"platformRelease": "test",
|
||||||
|
"uptime_in_millis": 1000,
|
||||||
|
},
|
||||||
|
"process": Object {
|
||||||
|
"event_loop_delay": 10,
|
||||||
|
"memory": Object {
|
||||||
|
"heap": Object {
|
||||||
|
"size_limit": 0,
|
||||||
|
"total_in_bytes": 0,
|
||||||
|
"used_in_bytes": 0,
|
||||||
|
},
|
||||||
|
"resident_set_size_in_bytes": 0,
|
||||||
|
},
|
||||||
|
"uptime_in_millis": 1000,
|
||||||
|
},
|
||||||
|
"requests": Object {
|
||||||
|
"disconnects": 10,
|
||||||
|
"total": 100,
|
||||||
|
},
|
||||||
|
"response_times": Object {
|
||||||
|
"average": 100,
|
||||||
|
"max": 200,
|
||||||
|
},
|
||||||
|
"timestamp": Any<String>,
|
||||||
|
}
|
||||||
|
`;
|
132
src/plugins/telemetry/server/collectors/ops_stats/index.test.ts
Normal file
132
src/plugins/telemetry/server/collectors/ops_stats/index.test.ts
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* 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 { Subject } from 'rxjs';
|
||||||
|
import { UsageCollectionSetup } from '../../../../../plugins/usage_collection/server';
|
||||||
|
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||||
|
import { CollectorOptions } from '../../../../../plugins/usage_collection/server/collector/collector';
|
||||||
|
|
||||||
|
import { registerOpsStatsCollector } from './';
|
||||||
|
import { OpsMetrics } from '../../../../../core/server';
|
||||||
|
|
||||||
|
describe('telemetry_ops_stats', () => {
|
||||||
|
let collector: CollectorOptions;
|
||||||
|
|
||||||
|
const usageCollectionMock: jest.Mocked<UsageCollectionSetup> = {
|
||||||
|
makeStatsCollector: jest.fn().mockImplementation(config => (collector = config)),
|
||||||
|
registerCollector: jest.fn(),
|
||||||
|
} as any;
|
||||||
|
|
||||||
|
const metrics$ = new Subject<OpsMetrics>();
|
||||||
|
const callCluster = jest.fn();
|
||||||
|
|
||||||
|
const metric: OpsMetrics = {
|
||||||
|
process: {
|
||||||
|
memory: {
|
||||||
|
heap: {
|
||||||
|
total_in_bytes: 0,
|
||||||
|
used_in_bytes: 0,
|
||||||
|
size_limit: 0,
|
||||||
|
},
|
||||||
|
resident_set_size_in_bytes: 0,
|
||||||
|
},
|
||||||
|
event_loop_delay: 10,
|
||||||
|
pid: 10,
|
||||||
|
uptime_in_millis: 1000,
|
||||||
|
},
|
||||||
|
os: {
|
||||||
|
platform: 'darwin',
|
||||||
|
platformRelease: 'test',
|
||||||
|
load: {
|
||||||
|
'1m': 0.5,
|
||||||
|
'5m': 1,
|
||||||
|
'15m': 3,
|
||||||
|
},
|
||||||
|
memory: {
|
||||||
|
total_in_bytes: 10,
|
||||||
|
free_in_bytes: 10,
|
||||||
|
used_in_bytes: 10,
|
||||||
|
},
|
||||||
|
uptime_in_millis: 1000,
|
||||||
|
},
|
||||||
|
response_times: { avg_in_millis: 100, max_in_millis: 200 },
|
||||||
|
requests: {
|
||||||
|
disconnects: 10,
|
||||||
|
total: 100,
|
||||||
|
statusCodes: { 200: 100 },
|
||||||
|
},
|
||||||
|
concurrent_connections: 20,
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeAll(() => registerOpsStatsCollector(usageCollectionMock, metrics$));
|
||||||
|
afterAll(() => jest.clearAllTimers());
|
||||||
|
|
||||||
|
test('registered collector is set', () => {
|
||||||
|
expect(collector).not.toBeUndefined();
|
||||||
|
expect(collector.type).toBe('kibana_stats');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('isReady should return false because no metrics have been provided yet', () => {
|
||||||
|
expect(collector.isReady()).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return something when there is a metric', async () => {
|
||||||
|
metrics$.next(metric);
|
||||||
|
expect(collector.isReady()).toBe(true);
|
||||||
|
expect(await collector.fetch(callCluster)).toMatchSnapshot({
|
||||||
|
concurrent_connections: 20,
|
||||||
|
os: {
|
||||||
|
load: {
|
||||||
|
'15m': 3,
|
||||||
|
'1m': 0.5,
|
||||||
|
'5m': 1,
|
||||||
|
},
|
||||||
|
memory: {
|
||||||
|
free_in_bytes: 10,
|
||||||
|
total_in_bytes: 10,
|
||||||
|
used_in_bytes: 10,
|
||||||
|
},
|
||||||
|
platform: 'darwin',
|
||||||
|
platformRelease: 'test',
|
||||||
|
uptime_in_millis: 1000,
|
||||||
|
},
|
||||||
|
process: {
|
||||||
|
event_loop_delay: 10,
|
||||||
|
memory: {
|
||||||
|
heap: {
|
||||||
|
size_limit: 0,
|
||||||
|
total_in_bytes: 0,
|
||||||
|
used_in_bytes: 0,
|
||||||
|
},
|
||||||
|
resident_set_size_in_bytes: 0,
|
||||||
|
},
|
||||||
|
uptime_in_millis: 1000,
|
||||||
|
},
|
||||||
|
requests: {
|
||||||
|
disconnects: 10,
|
||||||
|
total: 100,
|
||||||
|
},
|
||||||
|
response_times: {
|
||||||
|
average: 100,
|
||||||
|
max: 200,
|
||||||
|
},
|
||||||
|
timestamp: expect.any(String),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -17,4 +17,4 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { registerOpsStatsCollector } from './get_ops_stats_collector';
|
export { registerOpsStatsCollector } from './ops_stats_collector';
|
|
@ -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 { Observable } from 'rxjs';
|
||||||
|
import { cloneDeep } from 'lodash';
|
||||||
|
import moment from 'moment';
|
||||||
|
import { OpsMetrics } from 'kibana/server';
|
||||||
|
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
|
||||||
|
import { KIBANA_STATS_TYPE } from '../../../common/constants';
|
||||||
|
|
||||||
|
interface OpsStatsMetrics extends Omit<OpsMetrics, 'response_times'> {
|
||||||
|
timestamp: string;
|
||||||
|
response_times: {
|
||||||
|
average: number;
|
||||||
|
max: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a collector for Kibana Ops Stats
|
||||||
|
*/
|
||||||
|
export function getOpsStatsCollector(
|
||||||
|
usageCollection: UsageCollectionSetup,
|
||||||
|
metrics$: Observable<OpsMetrics>
|
||||||
|
) {
|
||||||
|
let lastMetrics: OpsStatsMetrics | null = null;
|
||||||
|
metrics$.subscribe(_metrics => {
|
||||||
|
const metrics = cloneDeep(_metrics);
|
||||||
|
// Ensure we only include the same data that Metricbeat collection would get
|
||||||
|
delete metrics.process.pid;
|
||||||
|
const responseTimes = {
|
||||||
|
average: metrics.response_times.avg_in_millis,
|
||||||
|
max: metrics.response_times.max_in_millis,
|
||||||
|
};
|
||||||
|
delete metrics.requests.statusCodes;
|
||||||
|
lastMetrics = {
|
||||||
|
...metrics,
|
||||||
|
response_times: responseTimes,
|
||||||
|
timestamp: moment.utc().toISOString(),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return usageCollection.makeStatsCollector({
|
||||||
|
type: KIBANA_STATS_TYPE,
|
||||||
|
isReady: () => !!lastMetrics,
|
||||||
|
fetch: () => lastMetrics,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function registerOpsStatsCollector(
|
||||||
|
usageCollection: UsageCollectionSetup,
|
||||||
|
metrics$: Observable<OpsMetrics>
|
||||||
|
) {
|
||||||
|
usageCollection.registerCollector(getOpsStatsCollector(usageCollection, metrics$));
|
||||||
|
}
|
|
@ -32,6 +32,8 @@ import {
|
||||||
SavedObjectsClient,
|
SavedObjectsClient,
|
||||||
Plugin,
|
Plugin,
|
||||||
Logger,
|
Logger,
|
||||||
|
SharedGlobalConfig,
|
||||||
|
MetricsServiceSetup,
|
||||||
} from '../../../core/server';
|
} from '../../../core/server';
|
||||||
import { registerRoutes } from './routes';
|
import { registerRoutes } from './routes';
|
||||||
import { registerCollection } from './telemetry_collection';
|
import { registerCollection } from './telemetry_collection';
|
||||||
|
@ -41,6 +43,8 @@ import {
|
||||||
registerTelemetryPluginUsageCollector,
|
registerTelemetryPluginUsageCollector,
|
||||||
registerManagementUsageCollector,
|
registerManagementUsageCollector,
|
||||||
registerApplicationUsageCollector,
|
registerApplicationUsageCollector,
|
||||||
|
registerKibanaUsageCollector,
|
||||||
|
registerOpsStatsCollector,
|
||||||
} from './collectors';
|
} from './collectors';
|
||||||
import { TelemetryConfigType } from './config';
|
import { TelemetryConfigType } from './config';
|
||||||
import { FetcherTask } from './fetcher';
|
import { FetcherTask } from './fetcher';
|
||||||
|
@ -61,6 +65,7 @@ export class TelemetryPlugin implements Plugin {
|
||||||
private readonly logger: Logger;
|
private readonly logger: Logger;
|
||||||
private readonly currentKibanaVersion: string;
|
private readonly currentKibanaVersion: string;
|
||||||
private readonly config$: Observable<TelemetryConfigType>;
|
private readonly config$: Observable<TelemetryConfigType>;
|
||||||
|
private readonly legacyConfig$: Observable<SharedGlobalConfig>;
|
||||||
private readonly isDev: boolean;
|
private readonly isDev: boolean;
|
||||||
private readonly fetcherTask: FetcherTask;
|
private readonly fetcherTask: FetcherTask;
|
||||||
private savedObjectsClient?: ISavedObjectsRepository;
|
private savedObjectsClient?: ISavedObjectsRepository;
|
||||||
|
@ -71,6 +76,7 @@ export class TelemetryPlugin implements Plugin {
|
||||||
this.isDev = initializerContext.env.mode.dev;
|
this.isDev = initializerContext.env.mode.dev;
|
||||||
this.currentKibanaVersion = initializerContext.env.packageInfo.version;
|
this.currentKibanaVersion = initializerContext.env.packageInfo.version;
|
||||||
this.config$ = initializerContext.config.create();
|
this.config$ = initializerContext.config.create();
|
||||||
|
this.legacyConfig$ = initializerContext.config.legacy.globalConfig$;
|
||||||
this.fetcherTask = new FetcherTask({
|
this.fetcherTask = new FetcherTask({
|
||||||
...initializerContext,
|
...initializerContext,
|
||||||
logger: this.logger,
|
logger: this.logger,
|
||||||
|
@ -78,15 +84,15 @@ export class TelemetryPlugin implements Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async setup(
|
public async setup(
|
||||||
core: CoreSetup,
|
{ elasticsearch, http, savedObjects, metrics }: CoreSetup,
|
||||||
{ usageCollection, telemetryCollectionManager }: TelemetryPluginsSetup
|
{ usageCollection, telemetryCollectionManager }: TelemetryPluginsSetup
|
||||||
) {
|
) {
|
||||||
const currentKibanaVersion = this.currentKibanaVersion;
|
const currentKibanaVersion = this.currentKibanaVersion;
|
||||||
const config$ = this.config$;
|
const config$ = this.config$;
|
||||||
const isDev = this.isDev;
|
const isDev = this.isDev;
|
||||||
|
|
||||||
registerCollection(telemetryCollectionManager, core.elasticsearch.dataClient);
|
registerCollection(telemetryCollectionManager, elasticsearch.dataClient);
|
||||||
const router = core.http.createRouter();
|
const router = http.createRouter();
|
||||||
|
|
||||||
registerRoutes({
|
registerRoutes({
|
||||||
config$,
|
config$,
|
||||||
|
@ -96,8 +102,8 @@ export class TelemetryPlugin implements Plugin {
|
||||||
telemetryCollectionManager,
|
telemetryCollectionManager,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.registerMappings(opts => core.savedObjects.registerType(opts));
|
this.registerMappings(opts => savedObjects.registerType(opts));
|
||||||
this.registerUsageCollectors(usageCollection, opts => core.savedObjects.registerType(opts));
|
this.registerUsageCollectors(usageCollection, metrics, opts => savedObjects.registerType(opts));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async start(core: CoreStart, { telemetryCollectionManager }: TelemetryPluginsStart) {
|
public async start(core: CoreStart, { telemetryCollectionManager }: TelemetryPluginsStart) {
|
||||||
|
@ -153,11 +159,14 @@ export class TelemetryPlugin implements Plugin {
|
||||||
|
|
||||||
private registerUsageCollectors(
|
private registerUsageCollectors(
|
||||||
usageCollection: UsageCollectionSetup,
|
usageCollection: UsageCollectionSetup,
|
||||||
|
metrics: MetricsServiceSetup,
|
||||||
registerType: SavedObjectsRegisterType
|
registerType: SavedObjectsRegisterType
|
||||||
) {
|
) {
|
||||||
const getSavedObjectsClient = () => this.savedObjectsClient;
|
const getSavedObjectsClient = () => this.savedObjectsClient;
|
||||||
const getUiSettingsClient = () => this.uiSettingsClient;
|
const getUiSettingsClient = () => this.uiSettingsClient;
|
||||||
|
|
||||||
|
registerOpsStatsCollector(usageCollection, metrics.getOpsMetrics$());
|
||||||
|
registerKibanaUsageCollector(usageCollection, this.legacyConfig$);
|
||||||
registerTelemetryPluginUsageCollector(usageCollection, {
|
registerTelemetryPluginUsageCollector(usageCollection, {
|
||||||
currentKibanaVersion: this.currentKibanaVersion,
|
currentKibanaVersion: this.currentKibanaVersion,
|
||||||
config$: this.config$,
|
config$: this.config$,
|
||||||
|
|
|
@ -55,6 +55,10 @@ export function handleKibanaStats(
|
||||||
...kibanaStats.os,
|
...kibanaStats.os,
|
||||||
};
|
};
|
||||||
const formattedOsStats = Object.entries(os).reduce((acc, [key, value]) => {
|
const formattedOsStats = Object.entries(os).reduce((acc, [key, value]) => {
|
||||||
|
if (typeof value !== 'string') {
|
||||||
|
// There are new fields reported now from the "os" property like "load", "memory", etc. They are objects.
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...acc,
|
...acc,
|
||||||
[`${key}s`]: [{ [key]: value, count: 1 }],
|
[`${key}s`]: [{ [key]: value, count: 1 }],
|
||||||
|
|
16
src/plugins/vis_default_editor/README.md
Normal file
16
src/plugins/vis_default_editor/README.md
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Visualization Deafult Editor plugin
|
||||||
|
|
||||||
|
The default editor is used in most primary visualizations, e.x. `Area`, `Data table`, `Pie`, etc.
|
||||||
|
It acts as a container for a particular visualization and options tabs. Contains the default "Data" tab in `public/components/sidebar/data_tab.tsx`.
|
||||||
|
The plugin exposes the static `DefaultEditorController` class to consume.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { DefaultEditorController } from '../../vis_default_editor/public';
|
||||||
|
|
||||||
|
const editor = new DefaultEditorController(
|
||||||
|
element,
|
||||||
|
vis,
|
||||||
|
eventEmitter,
|
||||||
|
embeddableHandler
|
||||||
|
);
|
||||||
|
```
|
|
@ -28,14 +28,13 @@ import {
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
import { IAggConfig } from 'src/plugins/data/public';
|
import { IAggConfig, TimeRange } from 'src/plugins/data/public';
|
||||||
import { DefaultEditorAggParams } from './agg_params';
|
import { DefaultEditorAggParams } from './agg_params';
|
||||||
import { DefaultEditorAggCommonProps } from './agg_common_props';
|
import { DefaultEditorAggCommonProps } from './agg_common_props';
|
||||||
import { AGGS_ACTION_KEYS, AggsAction } from './agg_group_state';
|
import { AGGS_ACTION_KEYS, AggsAction } from './agg_group_state';
|
||||||
import { RowsOrColumnsControl } from './controls/rows_or_columns';
|
import { RowsOrColumnsControl } from './controls/rows_or_columns';
|
||||||
import { RadiusRatioOptionControl } from './controls/radius_ratio_option';
|
import { RadiusRatioOptionControl } from './controls/radius_ratio_option';
|
||||||
import { getSchemaByName } from '../schemas';
|
import { getSchemaByName } from '../schemas';
|
||||||
import { TimeRange } from '../../../../../plugins/data/public';
|
|
||||||
import { buildAggDescription } from './agg_params_helper';
|
import { buildAggDescription } from './agg_params_helper';
|
||||||
|
|
||||||
export interface DefaultEditorAggProps extends DefaultEditorAggCommonProps {
|
export interface DefaultEditorAggProps extends DefaultEditorAggCommonProps {
|
|
@ -29,7 +29,7 @@ import {
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { IAggConfig, AggGroupNames } from '../../../../../plugins/data/public';
|
import { IAggConfig, AggGroupNames } from '../../../data/public';
|
||||||
import { Schema } from '../schemas';
|
import { Schema } from '../schemas';
|
||||||
|
|
||||||
interface DefaultEditorAggAddProps {
|
interface DefaultEditorAggAddProps {
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue