mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[ML] Move Index Data Visualizer into separate plugin (Part 1) (#100922)
* [ML] Add index visualizer * [ML] Readd support for global state * [ML] Add time buckets & fix dependencies * [ML] Working ver * [ML] Add back and boolean support * [ML] Remove old files inside ml * [ML] Rename files * [ML] Move field type icon * [ML] Create new folder structure * [ML] Organize index_data_visualizer * [ML] Move types into index_data_visualizer folder * [ML] Move more files into file_data_visualizer * [ML] Move more files into index_data_visualizer * [ML] Add new data visualizer model * [ML] Remove getVisualizerFieldStats which is not used by dv * [ML] Delete redundant folder * [ML] Copy old data visualizer routes to new plugin * [ML] Remove old routes * [ML] Disable for ml job cards tests for now * [ML] Remove todos * [ML] Move the toast error to the UI component * [ML] Fix map styling * [ML] Add runtime_mappings for internal/file_upload/time_field_range * [ML] Move routes into folder * [ML] Update permissions * [ML] Update texts * [ML] Update schemas import and api get_field_stats * [ML] Reorg folders into common * [ML] Update types & tests * [ML] Update internal/data_visualizer permissions and action panel tests * [ML] Update imports after #100863 * [ML] Fix CI * [ML] Rename folder from file_data_visualizer to data_visualizer * [ML] Rename i18n ids * [ML] Update fileDataVisualizer -> dataVisualizer dependency name in ml plugin * [ML] Remove ml prefix in data test subjs * [ML] Fix settings and docs * [ML] Update plugin description * [ML] Remove mlContext dependency completely * [ML] Set query to optional * Revert "[ML] Update plugin description" This reverts commit 4ab1a25c * [ML] Update plugins list docs * [ML] Fix types and i18n * [ML] Revert ml data test subj/class name changes * [ML] Split up data visualizer model, remove Logger * [ML] Remove empty file and indexPatternFieldEditor * [ML] Move imports of file_upload * [ML] Update plugin dependencies * Re-add missing data_visualizer.json * Remove capabilities in data_visualizer * Fix test subjs * Update ownership for data_visualizer and file_upload code to be ml * Update estypes after 98266 Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
8aa370ba3b
commit
65b8dda157
372 changed files with 6256 additions and 5096 deletions
46
.github/CODEOWNERS
vendored
46
.github/CODEOWNERS
vendored
|
@ -130,6 +130,8 @@
|
|||
|
||||
# ML team owns and maintains the transform plugin despite it living in the Data management section.
|
||||
/x-pack/plugins/transform/ @elastic/ml-ui
|
||||
/x-pack/plugins/data_visualizer/ @elastic/ml-ui
|
||||
/x-pack/plugins/file_upload/ @elastic/ml-ui
|
||||
/x-pack/test/accessibility/apps/transform.ts @elastic/ml-ui
|
||||
/x-pack/test/api_integration/apis/transform/ @elastic/ml-ui
|
||||
/x-pack/test/api_integration_basic/apis/transform/ @elastic/ml-ui
|
||||
|
@ -306,28 +308,28 @@
|
|||
/x-pack/plugins/enterprise_search/server/saved_objects/workplace_search/ @elastic/workplace-search-frontend
|
||||
|
||||
# Stack Management
|
||||
/src/plugins/dev_tools/ @elastic/kibana-stack-management
|
||||
/src/plugins/console/ @elastic/kibana-stack-management
|
||||
/src/plugins/es_ui_shared/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/cross_cluster_replication/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/index_lifecycle_management/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/console_extensions/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/grokdebugger/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/index_management/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/license_api_guard/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/license_management/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/painless_lab/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/remote_clusters/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/rollup/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/searchprofiler/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/snapshot_restore/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/upgrade_assistant/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/watcher/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/ingest_pipelines/ @elastic/kibana-stack-management
|
||||
/packages/kbn-ace/ @elastic/kibana-stack-management
|
||||
/packages/kbn-monaco/ @elastic/kibana-stack-management
|
||||
#CC# /x-pack/plugins/console_extensions/ @elastic/kibana-stack-management
|
||||
#CC# /x-pack/plugins/cross_cluster_replication/ @elastic/kibana-stack-management
|
||||
/src/plugins/dev_tools/ @elastic/kibana-stack-management
|
||||
/src/plugins/console/ @elastic/kibana-stack-management
|
||||
/src/plugins/es_ui_shared/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/cross_cluster_replication/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/index_lifecycle_management/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/console_extensions/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/grokdebugger/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/index_management/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/license_api_guard/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/license_management/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/painless_lab/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/remote_clusters/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/rollup/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/searchprofiler/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/snapshot_restore/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/upgrade_assistant/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/watcher/ @elastic/kibana-stack-management
|
||||
/x-pack/plugins/ingest_pipelines/ @elastic/kibana-stack-management
|
||||
/packages/kbn-ace/ @elastic/kibana-stack-management
|
||||
/packages/kbn-monaco/ @elastic/kibana-stack-management
|
||||
#CC# /x-pack/plugins/console_extensions/ @elastic/kibana-stack-management
|
||||
#CC# /x-pack/plugins/cross_cluster_replication/ @elastic/kibana-stack-management
|
||||
|
||||
# Security Solution
|
||||
/x-pack/test/endpoint_api_integration_no_ingest/ @elastic/security-solution
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"id": "fileDataVisualizer",
|
||||
"id": "dataVisualizer",
|
||||
"client": {
|
||||
"classes": [],
|
||||
"functions": [],
|
||||
|
@ -8,18 +8,18 @@
|
|||
"misc": [],
|
||||
"objects": [],
|
||||
"start": {
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"id": "def-public.FileDataVisualizerPluginStart",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-public.DataVisualizerPluginStart",
|
||||
"type": "Type",
|
||||
"tags": [],
|
||||
"label": "FileDataVisualizerPluginStart",
|
||||
"label": "DataVisualizerPluginStart",
|
||||
"description": [],
|
||||
"signature": [
|
||||
"{ getFileDataVisualizerComponent: () => Promise<React.FC<{}>>; getMaxBytesFormatted: () => string; }"
|
||||
],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/public/plugin.ts",
|
||||
"lineNumber": 36
|
||||
"path": "x-pack/plugins/data_visualizer/public/plugin.ts",
|
||||
"lineNumber": 33
|
||||
},
|
||||
"deprecated": false,
|
||||
"lifecycle": "start",
|
||||
|
@ -39,72 +39,72 @@
|
|||
"functions": [],
|
||||
"interfaces": [
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.DataVisualizerTableState",
|
||||
"type": "Interface",
|
||||
"tags": [],
|
||||
"label": "DataVisualizerTableState",
|
||||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/types.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/types.ts",
|
||||
"lineNumber": 14
|
||||
},
|
||||
"deprecated": false,
|
||||
"children": [
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.DataVisualizerTableState.pageSize",
|
||||
"type": "number",
|
||||
"tags": [],
|
||||
"label": "pageSize",
|
||||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/types.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/types.ts",
|
||||
"lineNumber": 15
|
||||
},
|
||||
"deprecated": false
|
||||
},
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.DataVisualizerTableState.pageIndex",
|
||||
"type": "number",
|
||||
"tags": [],
|
||||
"label": "pageIndex",
|
||||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/types.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/types.ts",
|
||||
"lineNumber": 16
|
||||
},
|
||||
"deprecated": false
|
||||
},
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.DataVisualizerTableState.sortField",
|
||||
"type": "string",
|
||||
"tags": [],
|
||||
"label": "sortField",
|
||||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/types.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/types.ts",
|
||||
"lineNumber": 17
|
||||
},
|
||||
"deprecated": false
|
||||
},
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.DataVisualizerTableState.sortDirection",
|
||||
"type": "string",
|
||||
"tags": [],
|
||||
"label": "sortDirection",
|
||||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/types.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/types.ts",
|
||||
"lineNumber": 18
|
||||
},
|
||||
"deprecated": false
|
||||
},
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.DataVisualizerTableState.visibleFieldTypes",
|
||||
"type": "Array",
|
||||
"tags": [],
|
||||
|
@ -114,13 +114,13 @@
|
|||
"string[]"
|
||||
],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/types.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/types.ts",
|
||||
"lineNumber": 19
|
||||
},
|
||||
"deprecated": false
|
||||
},
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.DataVisualizerTableState.visibleFieldNames",
|
||||
"type": "Array",
|
||||
"tags": [],
|
||||
|
@ -130,20 +130,20 @@
|
|||
"string[]"
|
||||
],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/types.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/types.ts",
|
||||
"lineNumber": 20
|
||||
},
|
||||
"deprecated": false
|
||||
},
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.DataVisualizerTableState.showDistributions",
|
||||
"type": "boolean",
|
||||
"tags": [],
|
||||
"label": "showDistributions",
|
||||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/types.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/types.ts",
|
||||
"lineNumber": 21
|
||||
},
|
||||
"deprecated": false
|
||||
|
@ -155,7 +155,7 @@
|
|||
"enums": [],
|
||||
"misc": [
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.ABSOLUTE_MAX_FILE_SIZE_BYTES",
|
||||
"type": "number",
|
||||
"tags": [],
|
||||
|
@ -165,14 +165,14 @@
|
|||
"1073741274"
|
||||
],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/constants.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/constants.ts",
|
||||
"lineNumber": 14
|
||||
},
|
||||
"deprecated": false,
|
||||
"initialIsOpen": false
|
||||
},
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.FILE_SIZE_DISPLAY_FORMAT",
|
||||
"type": "string",
|
||||
"tags": [],
|
||||
|
@ -182,14 +182,14 @@
|
|||
"\"0,0.[0] b\""
|
||||
],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/constants.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/constants.ts",
|
||||
"lineNumber": 15
|
||||
},
|
||||
"deprecated": false,
|
||||
"initialIsOpen": false
|
||||
},
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.INDEX_META_DATA_CREATED_BY",
|
||||
"type": "string",
|
||||
"tags": [],
|
||||
|
@ -199,14 +199,14 @@
|
|||
"\"file-data-visualizer\""
|
||||
],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/constants.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/constants.ts",
|
||||
"lineNumber": 19
|
||||
},
|
||||
"deprecated": false,
|
||||
"initialIsOpen": false
|
||||
},
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.InputData",
|
||||
"type": "Type",
|
||||
"tags": [],
|
||||
|
@ -216,31 +216,31 @@
|
|||
"any[]"
|
||||
],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/types.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/types.ts",
|
||||
"lineNumber": 10
|
||||
},
|
||||
"deprecated": false,
|
||||
"initialIsOpen": false
|
||||
},
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.JobFieldType",
|
||||
"type": "Type",
|
||||
"tags": [],
|
||||
"label": "JobFieldType",
|
||||
"description": [],
|
||||
"signature": [
|
||||
"\"number\" | \"boolean\" | \"date\" | \"keyword\" | \"text\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"unknown\""
|
||||
"\"number\" | \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"unknown\""
|
||||
],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/types.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/types.ts",
|
||||
"lineNumber": 12
|
||||
},
|
||||
"deprecated": false,
|
||||
"initialIsOpen": false
|
||||
},
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.MAX_FILE_SIZE",
|
||||
"type": "string",
|
||||
"tags": [],
|
||||
|
@ -250,14 +250,14 @@
|
|||
"\"100MB\""
|
||||
],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/constants.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/constants.ts",
|
||||
"lineNumber": 11
|
||||
},
|
||||
"deprecated": false,
|
||||
"initialIsOpen": false
|
||||
},
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.MAX_FILE_SIZE_BYTES",
|
||||
"type": "number",
|
||||
"tags": [],
|
||||
|
@ -267,28 +267,28 @@
|
|||
"104857600"
|
||||
],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/constants.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/constants.ts",
|
||||
"lineNumber": 12
|
||||
},
|
||||
"deprecated": false,
|
||||
"initialIsOpen": false
|
||||
},
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.MB",
|
||||
"type": "number",
|
||||
"tags": [],
|
||||
"label": "MB",
|
||||
"description": [],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/constants.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/constants.ts",
|
||||
"lineNumber": 10
|
||||
},
|
||||
"deprecated": false,
|
||||
"initialIsOpen": false
|
||||
},
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.UI_SETTING_MAX_FILE_SIZE",
|
||||
"type": "string",
|
||||
"tags": [],
|
||||
|
@ -298,7 +298,7 @@
|
|||
"\"fileUpload:maxFileSize\""
|
||||
],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/constants.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/constants.ts",
|
||||
"lineNumber": 8
|
||||
},
|
||||
"deprecated": false,
|
||||
|
@ -307,7 +307,7 @@
|
|||
],
|
||||
"objects": [
|
||||
{
|
||||
"parentPluginId": "fileDataVisualizer",
|
||||
"parentPluginId": "dataVisualizer",
|
||||
"id": "def-common.JOB_FIELD_TYPES",
|
||||
"type": "Object",
|
||||
"tags": [],
|
||||
|
@ -317,7 +317,7 @@
|
|||
"{ readonly BOOLEAN: \"boolean\"; readonly DATE: \"date\"; readonly GEO_POINT: \"geo_point\"; readonly GEO_SHAPE: \"geo_shape\"; readonly IP: \"ip\"; readonly KEYWORD: \"keyword\"; readonly NUMBER: \"number\"; readonly TEXT: \"text\"; readonly UNKNOWN: \"unknown\"; }"
|
||||
],
|
||||
"source": {
|
||||
"path": "x-pack/plugins/file_data_visualizer/common/constants.ts",
|
||||
"path": "x-pack/plugins/data_visualizer/common/constants.ts",
|
||||
"lineNumber": 21
|
||||
},
|
||||
"deprecated": false,
|
||||
|
@ -325,4 +325,4 @@
|
|||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -369,6 +369,10 @@ The client-side plugin configures following values:
|
|||
|The data_enhanced plugin is the x-pack counterpart to the src/plguins/data plugin.
|
||||
|
||||
|
||||
|{kib-repo}blob/{branch}/x-pack/plugins/data_visualizer/README.md[dataVisualizer]
|
||||
|The data_visualizer plugin enables you to explore the fields in your data.
|
||||
|
||||
|
||||
|{kib-repo}blob/{branch}/x-pack/plugins/discover_enhanced/README.md[discoverEnhanced]
|
||||
|Contains the enhancements to the OSS discover app.
|
||||
|
||||
|
@ -396,10 +400,6 @@ actitivies.
|
|||
|The features plugin enhance Kibana with a per-feature privilege system.
|
||||
|
||||
|
||||
|{kib-repo}blob/{branch}/x-pack/plugins/file_data_visualizer[fileDataVisualizer]
|
||||
|WARNING: Missing README.
|
||||
|
||||
|
||||
|{kib-repo}blob/{branch}/x-pack/plugins/file_upload[fileUpload]
|
||||
|WARNING: Missing README.
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ pageLoadAssetSize:
|
|||
indexPatternFieldEditor: 90489
|
||||
osquery: 107090
|
||||
fileUpload: 25664
|
||||
fileDataVisualizer: 27530
|
||||
dataVisualizer: 27530
|
||||
banners: 17946
|
||||
mapsEms: 26072
|
||||
timelines: 28613
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
"xpack.endpoint": "plugins/endpoint",
|
||||
"xpack.enterpriseSearch": "plugins/enterprise_search",
|
||||
"xpack.features": "plugins/features",
|
||||
"xpack.fileDataVisualizer": "plugins/file_data_visualizer",
|
||||
"xpack.dataVisualizer": "plugins/data_visualizer",
|
||||
"xpack.fileUpload": "plugins/file_upload",
|
||||
"xpack.globalSearch": ["plugins/global_search"],
|
||||
"xpack.globalSearchBar": ["plugins/global_search_bar"],
|
||||
|
|
1
x-pack/plugins/data_visualizer/README.md
Normal file
1
x-pack/plugins/data_visualizer/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
The data_visualizer plugin enables you to explore the fields in your data.
|
|
@ -29,3 +29,5 @@ export const JOB_FIELD_TYPES = {
|
|||
TEXT: 'text',
|
||||
UNKNOWN: 'unknown',
|
||||
} as const;
|
||||
|
||||
export const OMIT_FIELDS: string[] = ['_source', '_type', '_index', '_id', '_version', '_score'];
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { JobFieldType } from './index';
|
||||
|
||||
export interface Percentile {
|
||||
percent: number;
|
||||
minValue: number;
|
||||
maxValue: number;
|
||||
}
|
||||
|
||||
export interface FieldRequestConfig {
|
||||
fieldName?: string;
|
||||
type: JobFieldType;
|
||||
cardinality: number;
|
||||
}
|
||||
|
||||
export interface DocumentCountBuckets {
|
||||
[key: string]: number;
|
||||
}
|
||||
|
||||
export interface DocumentCounts {
|
||||
buckets?: DocumentCountBuckets;
|
||||
interval?: number;
|
||||
}
|
||||
|
||||
export interface FieldVisStats {
|
||||
cardinality?: number;
|
||||
count?: number;
|
||||
sampleCount?: number;
|
||||
trueCount?: number;
|
||||
falseCount?: number;
|
||||
earliest?: number;
|
||||
latest?: number;
|
||||
documentCounts?: {
|
||||
buckets?: DocumentCountBuckets;
|
||||
interval?: number;
|
||||
};
|
||||
avg?: number;
|
||||
distribution?: {
|
||||
percentiles: Percentile[];
|
||||
maxPercentile: number;
|
||||
minPercentile: 0;
|
||||
};
|
||||
fieldName?: string;
|
||||
isTopValuesSampled?: boolean;
|
||||
max?: number;
|
||||
median?: number;
|
||||
min?: number;
|
||||
topValues?: Array<{ key: number | string; doc_count: number }>;
|
||||
topValuesSampleSize?: number;
|
||||
topValuesSamplerShardSize?: number;
|
||||
examples?: Array<string | object>;
|
||||
timeRangeEarliest?: number;
|
||||
timeRangeLatest?: number;
|
||||
}
|
|
@ -5,12 +5,17 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { JOB_FIELD_TYPES } from './constants';
|
||||
|
||||
import type { SimpleSavedObject } from 'kibana/public';
|
||||
export type { JobFieldType } from './job_field_type';
|
||||
export type {
|
||||
FieldRequestConfig,
|
||||
DocumentCountBuckets,
|
||||
DocumentCounts,
|
||||
FieldVisStats,
|
||||
Percentile,
|
||||
} from './field_request_config';
|
||||
export type InputData = any[];
|
||||
|
||||
export type JobFieldType = typeof JOB_FIELD_TYPES[keyof typeof JOB_FIELD_TYPES];
|
||||
|
||||
export interface DataVisualizerTableState {
|
||||
pageSize: number;
|
||||
pageIndex: number;
|
||||
|
@ -20,3 +25,5 @@ export interface DataVisualizerTableState {
|
|||
visibleFieldNames: string[];
|
||||
showDistributions: boolean;
|
||||
}
|
||||
|
||||
export type SavedSearchSavedObject = SimpleSavedObject<any>;
|
|
@ -5,8 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { FieldVisConfig, FileBasedFieldVisConfig } from './field_vis_config';
|
||||
import { estypes } from '@elastic/elasticsearch';
|
||||
|
||||
export interface FieldDataRowProps {
|
||||
config: FieldVisConfig | FileBasedFieldVisConfig;
|
||||
export interface IndicesOptions {
|
||||
allow_no_indices?: boolean;
|
||||
expand_wildcards?: estypes.ExpandWildcards;
|
||||
ignore_unavailable?: boolean;
|
||||
}
|
|
@ -5,6 +5,5 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { FileDataVisualizerPlugin } from './plugin';
|
||||
|
||||
export const plugin = () => new FileDataVisualizerPlugin();
|
||||
import { JOB_FIELD_TYPES } from '../constants';
|
||||
export type JobFieldType = typeof JOB_FIELD_TYPES[keyof typeof JOB_FIELD_TYPES];
|
|
@ -5,7 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export interface CombinedQuery {
|
||||
searchString: string | { [key: string]: any };
|
||||
searchQueryLanguage: string;
|
||||
export interface GetTimeFieldRangeResponse {
|
||||
success: boolean;
|
||||
start: { epoch: number; string: string };
|
||||
end: { epoch: number; string: string };
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { estypes } from '@elastic/elasticsearch';
|
||||
|
||||
export type Datafeed = estypes.MlDatafeed;
|
||||
export type Aggregation = Record<string, estypes.AggregationsAggregationContainer>;
|
||||
|
||||
export function getAggregations<T>(obj: any): T | undefined {
|
||||
if (obj?.aggregations !== undefined) return obj.aggregations;
|
||||
if (obj?.aggs !== undefined) return obj.aggs;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export const getDatafeedAggregations = (
|
||||
datafeedConfig: Partial<Datafeed> | undefined
|
||||
): Aggregation | undefined => {
|
||||
return getAggregations<Aggregation>(datafeedConfig);
|
||||
};
|
36
x-pack/plugins/data_visualizer/common/utils/object_utils.ts
Normal file
36
x-pack/plugins/data_visualizer/common/utils/object_utils.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
/*
|
||||
* A type guard to check record like object structures.
|
||||
*
|
||||
* Examples:
|
||||
* - `isPopulatedObject({...})`
|
||||
* Limits type to Record<string, unknown>
|
||||
*
|
||||
* - `isPopulatedObject({...}, ['attribute'])`
|
||||
* Limits type to Record<'attribute', unknown>
|
||||
*
|
||||
* - `isPopulatedObject<keyof MyInterface>({...})`
|
||||
* Limits type to a record with keys of the given interface.
|
||||
* Note that you might want to add keys from the interface to the
|
||||
* array of requiredAttributes to satisfy runtime requirements.
|
||||
* Otherwise you'd just satisfy TS requirements but might still
|
||||
* run into runtime issues.
|
||||
*/
|
||||
export const isPopulatedObject = <U extends string = string>(
|
||||
arg: unknown,
|
||||
requiredAttributes: U[] = []
|
||||
): arg is Record<U, unknown> => {
|
||||
return (
|
||||
typeof arg === 'object' &&
|
||||
arg !== null &&
|
||||
Object.keys(arg).length > 0 &&
|
||||
(requiredAttributes.length === 0 ||
|
||||
requiredAttributes.every((d) => ({}.hasOwnProperty.call(arg, d))))
|
||||
);
|
||||
};
|
76
x-pack/plugins/data_visualizer/common/utils/query_utils.ts
Normal file
76
x-pack/plugins/data_visualizer/common/utils/query_utils.ts
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { estypes } from '@elastic/elasticsearch';
|
||||
/*
|
||||
* Contains utility functions for building and processing queries.
|
||||
*/
|
||||
|
||||
// Builds the base filter criteria used in queries,
|
||||
// adding criteria for the time range and an optional query.
|
||||
export function buildBaseFilterCriteria(
|
||||
timeFieldName?: string,
|
||||
earliestMs?: number,
|
||||
latestMs?: number,
|
||||
query?: object
|
||||
) {
|
||||
const filterCriteria = [];
|
||||
if (timeFieldName && earliestMs && latestMs) {
|
||||
filterCriteria.push({
|
||||
range: {
|
||||
[timeFieldName]: {
|
||||
gte: earliestMs,
|
||||
lte: latestMs,
|
||||
format: 'epoch_millis',
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (query) {
|
||||
filterCriteria.push(query);
|
||||
}
|
||||
|
||||
return filterCriteria;
|
||||
}
|
||||
|
||||
// Wraps the supplied aggregations in a sampler aggregation.
|
||||
// A supplied samplerShardSize (the shard_size parameter of the sampler aggregation)
|
||||
// of less than 1 indicates no sampling, and the aggs are returned as-is.
|
||||
export function buildSamplerAggregation(
|
||||
aggs: any,
|
||||
samplerShardSize: number
|
||||
): Record<string, estypes.AggregationsAggregationContainer> {
|
||||
if (samplerShardSize < 1) {
|
||||
return aggs;
|
||||
}
|
||||
|
||||
return {
|
||||
sample: {
|
||||
sampler: {
|
||||
shard_size: samplerShardSize,
|
||||
},
|
||||
aggs,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Returns the path of aggregations in the elasticsearch response, as an array,
|
||||
// depending on whether sampling is being used.
|
||||
// A supplied samplerShardSize (the shard_size parameter of the sampler aggregation)
|
||||
// of less than 1 indicates no sampling, and an empty array is returned.
|
||||
export function getSamplerAggregationsResponsePath(samplerShardSize: number): string[] {
|
||||
return samplerShardSize > 0 ? ['sample'] : [];
|
||||
}
|
||||
|
||||
// Returns a name which is safe to use in elasticsearch aggregations for the supplied
|
||||
// field name. Aggregation names must be alpha-numeric and can only contain '_' and '-' characters,
|
||||
// so if the supplied field names contains disallowed characters, the provided index
|
||||
// identifier is used to return a safe 'dummy' name in the format 'field_index' e.g. field_0, field_1
|
||||
export function getSafeAggregationName(fieldName: string, index: number): string {
|
||||
return fieldName.match(/^[a-zA-Z0-9-_.]+$/) ? fieldName : `field_${index}`;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { estypes } from '@elastic/elasticsearch';
|
||||
import { isPopulatedObject } from './object_utils';
|
||||
import { RUNTIME_FIELD_TYPES } from '../../../../../src/plugins/data/common';
|
||||
|
||||
type RuntimeType = typeof RUNTIME_FIELD_TYPES[number];
|
||||
|
||||
export function isRuntimeField(arg: unknown): arg is estypes.MappingRuntimeField {
|
||||
return (
|
||||
((isPopulatedObject(arg, ['type']) && Object.keys(arg).length === 1) ||
|
||||
(isPopulatedObject(arg, ['type', 'script']) &&
|
||||
Object.keys(arg).length === 2 &&
|
||||
(typeof arg.script === 'string' ||
|
||||
(isPopulatedObject(arg.script, ['source']) &&
|
||||
Object.keys(arg.script).length === 1 &&
|
||||
typeof arg.script.source === 'string')))) &&
|
||||
RUNTIME_FIELD_TYPES.includes(arg.type as RuntimeType)
|
||||
);
|
||||
}
|
||||
|
||||
export function isRuntimeMappings(arg: unknown): arg is estypes.MappingRuntimeFields {
|
||||
return isPopulatedObject(arg) && Object.values(arg).every((d) => isRuntimeField(d));
|
||||
}
|
23
x-pack/plugins/data_visualizer/common/utils/string_utils.ts
Normal file
23
x-pack/plugins/data_visualizer/common/utils/string_utils.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a deterministic number based hash out of a string.
|
||||
*/
|
||||
export function stringHash(str: string): number {
|
||||
let hash = 0;
|
||||
let chr = 0;
|
||||
if (str.length === 0) {
|
||||
return hash;
|
||||
}
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
chr = str.charCodeAt(i);
|
||||
hash = (hash << 5) - hash + chr; // eslint-disable-line no-bitwise
|
||||
hash |= 0; // eslint-disable-line no-bitwise
|
||||
}
|
||||
return hash < 0 ? hash * -2 : hash;
|
||||
}
|
|
@ -8,5 +8,5 @@
|
|||
module.exports = {
|
||||
preset: '@kbn/test',
|
||||
rootDir: '../../..',
|
||||
roots: ['<rootDir>/x-pack/plugins/file_data_visualizer'],
|
||||
roots: ['<rootDir>/x-pack/plugins/data_visualizer'],
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"id": "fileDataVisualizer",
|
||||
"id": "dataVisualizer",
|
||||
"version": "8.0.0",
|
||||
"kibanaVersion": "kibana",
|
||||
"server": true,
|
||||
|
@ -15,7 +15,8 @@
|
|||
"optionalPlugins": [
|
||||
"security",
|
||||
"maps",
|
||||
"home"
|
||||
"home",
|
||||
"lens"
|
||||
],
|
||||
"requiredBundles": [
|
||||
"kibanaReact",
|
|
@ -6,9 +6,13 @@
|
|||
*/
|
||||
|
||||
import { lazyLoadModules } from '../lazy_load_bundle';
|
||||
import { FileDataVisualizer } from '../application';
|
||||
import type { FileDataVisualizerSpec, IndexDataVisualizerSpec } from '../application';
|
||||
|
||||
export async function getFileDataVisualizerComponent(): Promise<typeof FileDataVisualizer> {
|
||||
export async function getFileDataVisualizerComponent(): Promise<FileDataVisualizerSpec> {
|
||||
const modules = await lazyLoadModules();
|
||||
return modules.FileDataVisualizer;
|
||||
}
|
||||
export async function getIndexDataVisualizerComponent(): Promise<IndexDataVisualizerSpec> {
|
||||
const modules = await lazyLoadModules();
|
||||
return modules.IndexDataVisualizer;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
@import 'common/components/index';
|
||||
@import 'file_data_visualizer/index';
|
|
@ -0,0 +1,4 @@
|
|||
@import 'embedded_map/index';
|
||||
@import 'experimental_badge/index';
|
||||
@import 'stats_table/index';
|
||||
@import 'top_values/top_values';
|
|
@ -29,7 +29,7 @@ import {
|
|||
removeCombinedFieldsFromMappings,
|
||||
removeCombinedFieldsFromPipeline,
|
||||
} from './utils';
|
||||
import { FindFileStructureResponse } from '../../../../../file_upload/common';
|
||||
import { FindFileStructureResponse } from '../../../../../../file_upload/common';
|
||||
|
||||
interface Props {
|
||||
mappingsString: string;
|
||||
|
@ -110,7 +110,7 @@ export class CombinedFieldsForm extends Component<Props, State> {
|
|||
return JSON.parse(this.props.mappingsString);
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
i18n.translate('xpack.fileDataVisualizer.combinedFieldsForm.mappingsParseError', {
|
||||
i18n.translate('xpack.dataVisualizer.combinedFieldsForm.mappingsParseError', {
|
||||
defaultMessage: 'Error parsing mappings: {error}',
|
||||
values: { error: error.message },
|
||||
})
|
||||
|
@ -123,7 +123,7 @@ export class CombinedFieldsForm extends Component<Props, State> {
|
|||
return JSON.parse(this.props.pipelineString);
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
i18n.translate('xpack.fileDataVisualizer.combinedFieldsForm.pipelineParseError', {
|
||||
i18n.translate('xpack.dataVisualizer.combinedFieldsForm.pipelineParseError', {
|
||||
defaultMessage: 'Error parsing pipeline: {error}',
|
||||
values: { error: error.message },
|
||||
})
|
||||
|
@ -149,9 +149,12 @@ export class CombinedFieldsForm extends Component<Props, State> {
|
|||
};
|
||||
|
||||
render() {
|
||||
const geoPointLabel = i18n.translate('xpack.fileDataVisualizer.geoPointCombinedFieldLabel', {
|
||||
defaultMessage: 'Add geo point field',
|
||||
});
|
||||
const geoPointLabel = i18n.translate(
|
||||
'xpack.dataVisualizer.file.geoPointForm.combinedFieldLabel',
|
||||
{
|
||||
defaultMessage: 'Add geo point field',
|
||||
}
|
||||
);
|
||||
const panels = [
|
||||
{
|
||||
id: 0,
|
||||
|
@ -176,7 +179,7 @@ export class CombinedFieldsForm extends Component<Props, State> {
|
|||
];
|
||||
return (
|
||||
<EuiFormRow
|
||||
label={i18n.translate('xpack.fileDataVisualizer.combinedFieldsLabel', {
|
||||
label={i18n.translate('xpack.dataVisualizer.combinedFieldsLabel', {
|
||||
defaultMessage: 'Combined fields',
|
||||
})}
|
||||
>
|
||||
|
@ -192,15 +195,12 @@ export class CombinedFieldsForm extends Component<Props, State> {
|
|||
iconType="trash"
|
||||
color="danger"
|
||||
onClick={this.removeCombinedField.bind(null, idx)}
|
||||
title={i18n.translate('xpack.fileDataVisualizer.removeCombinedFieldsLabel', {
|
||||
title={i18n.translate('xpack.dataVisualizer.removeCombinedFieldsLabel', {
|
||||
defaultMessage: 'Remove combined field',
|
||||
})}
|
||||
aria-label={i18n.translate('xpack.dataVisualizer.removeCombinedFieldsLabel', {
|
||||
defaultMessage: 'Remove combined field',
|
||||
})}
|
||||
aria-label={i18n.translate(
|
||||
'xpack.fileDataVisualizer.removeCombinedFieldsLabel',
|
||||
{
|
||||
defaultMessage: 'Remove combined field',
|
||||
}
|
||||
)}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
|
@ -216,7 +216,7 @@ export class CombinedFieldsForm extends Component<Props, State> {
|
|||
isDisabled={this.props.isDisabled}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.addCombinedFieldsLabel"
|
||||
id="xpack.dataVisualizer.addCombinedFieldsLabel"
|
||||
defaultMessage="Add combined field"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
|
@ -20,10 +20,10 @@ export function CombinedFieldsReadOnlyForm({
|
|||
}) {
|
||||
return combinedFields.length ? (
|
||||
<EuiFormRow
|
||||
label={i18n.translate('xpack.fileDataVisualizer.combinedFieldsReadOnlyLabel', {
|
||||
label={i18n.translate('xpack.dataVisualizer.combinedFieldsReadOnlyLabel', {
|
||||
defaultMessage: 'Combined fields',
|
||||
})}
|
||||
helpText={i18n.translate('xpack.fileDataVisualizer.combinedFieldsReadOnlyHelpTextLabel', {
|
||||
helpText={i18n.translate('xpack.dataVisualizer.combinedFieldsReadOnlyHelpTextLabel', {
|
||||
defaultMessage: 'Edit combined fields in advanced tab',
|
||||
})}
|
||||
>
|
|
@ -29,7 +29,7 @@ import {
|
|||
getFieldNames,
|
||||
getNameCollisionMsg,
|
||||
} from './utils';
|
||||
import { FindFileStructureResponse } from '../../../../../file_upload/common';
|
||||
import { FindFileStructureResponse } from '../../../../../../file_upload/common';
|
||||
|
||||
interface Props {
|
||||
addCombinedField: (combinedField: CombinedField) => void;
|
||||
|
@ -119,7 +119,7 @@ export class GeoPointForm extends Component<Props, State> {
|
|||
return (
|
||||
<Fragment>
|
||||
<EuiFormRow
|
||||
label={i18n.translate('xpack.fileDataVisualizer.geoPointForm.latFieldLabel', {
|
||||
label={i18n.translate('xpack.dataVisualizer.file.geoPointForm.latFieldLabel', {
|
||||
defaultMessage: 'Latitude field',
|
||||
})}
|
||||
>
|
||||
|
@ -131,7 +131,7 @@ export class GeoPointForm extends Component<Props, State> {
|
|||
</EuiFormRow>
|
||||
|
||||
<EuiFormRow
|
||||
label={i18n.translate('xpack.fileDataVisualizer.geoPointForm.lonFieldLabel', {
|
||||
label={i18n.translate('xpack.dataVisualizer.file.geoPointForm.lonFieldLabel', {
|
||||
defaultMessage: 'Longitude field',
|
||||
})}
|
||||
>
|
||||
|
@ -143,7 +143,7 @@ export class GeoPointForm extends Component<Props, State> {
|
|||
</EuiFormRow>
|
||||
|
||||
<EuiFormRow
|
||||
label={i18n.translate('xpack.fileDataVisualizer.geoPointForm.geoPointFieldLabel', {
|
||||
label={i18n.translate('xpack.dataVisualizer.file.geoPointForm.geoPointFieldLabel', {
|
||||
defaultMessage: 'Geo point field',
|
||||
})}
|
||||
isInvalid={this.state.geoPointFieldError !== ''}
|
||||
|
@ -154,7 +154,7 @@ export class GeoPointForm extends Component<Props, State> {
|
|||
onChange={this.onGeoPointFieldChange}
|
||||
isInvalid={this.state.geoPointFieldError !== ''}
|
||||
aria-label={i18n.translate(
|
||||
'xpack.fileDataVisualizer.geoPointForm.geoPointFieldAriaLabel',
|
||||
'xpack.dataVisualizer.file.geoPointForm.geoPointFieldAriaLabel',
|
||||
{
|
||||
defaultMessage: 'Geo point field, required field',
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ export class GeoPointForm extends Component<Props, State> {
|
|||
onClick={this.onSubmit}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.geoPointForm.submitButtonLabel"
|
||||
id="xpack.dataVisualizer.file.geoPointForm.submitButtonLabel"
|
||||
defaultMessage="Add"
|
||||
/>
|
||||
</EuiButton>
|
|
@ -13,7 +13,7 @@ import {
|
|||
FindFileStructureResponse,
|
||||
IngestPipeline,
|
||||
Mappings,
|
||||
} from '../../../../../file_upload/common';
|
||||
} from '../../../../../../file_upload/common';
|
||||
|
||||
const COMMON_LAT_NAMES = ['latitude', 'lat'];
|
||||
const COMMON_LON_NAMES = ['longitude', 'long', 'lon'];
|
||||
|
@ -127,7 +127,7 @@ export function createGeoPointCombinedField(
|
|||
}
|
||||
|
||||
export function getNameCollisionMsg(name: string) {
|
||||
return i18n.translate('xpack.fileDataVisualizer.nameCollisionMsg', {
|
||||
return i18n.translate('xpack.dataVisualizer.nameCollisionMsg', {
|
||||
defaultMessage: '"{name}" already exists, please provide a unique name',
|
||||
values: { name },
|
||||
});
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { debounce } from 'lodash';
|
||||
|
||||
import { EuiSuperDatePicker, OnRefreshProps } from '@elastic/eui';
|
||||
import {
|
||||
TimeHistoryContract,
|
||||
TimeRange,
|
||||
UI_SETTINGS,
|
||||
} from '../../../../../../../../src/plugins/data/public';
|
||||
|
||||
import { useUrlState } from '../../util/url_state';
|
||||
import { useDataVisualizerKibana } from '../../../kibana_context';
|
||||
import { dataVisualizerTimefilterRefresh$ } from '../../../index_data_visualizer/services/timefilter_refresh_service';
|
||||
|
||||
interface TimePickerQuickRange {
|
||||
from: string;
|
||||
to: string;
|
||||
display: string;
|
||||
}
|
||||
|
||||
interface Duration {
|
||||
start: string;
|
||||
end: string;
|
||||
}
|
||||
|
||||
interface RefreshInterval {
|
||||
pause: boolean;
|
||||
value: number;
|
||||
}
|
||||
|
||||
function getRecentlyUsedRangesFactory(timeHistory: TimeHistoryContract) {
|
||||
return function (): Duration[] {
|
||||
return (
|
||||
timeHistory.get()?.map(({ from, to }: TimeRange) => {
|
||||
return {
|
||||
start: from,
|
||||
end: to,
|
||||
};
|
||||
}) ?? []
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
function updateLastRefresh(timeRange: OnRefreshProps) {
|
||||
dataVisualizerTimefilterRefresh$.next({ lastRefresh: Date.now(), timeRange });
|
||||
}
|
||||
|
||||
export const DatePickerWrapper: FC = () => {
|
||||
const { services } = useDataVisualizerKibana();
|
||||
const config = services.uiSettings;
|
||||
const { timefilter, history } = services.data.query.timefilter;
|
||||
|
||||
const [globalState, setGlobalState] = useUrlState('_g');
|
||||
const getRecentlyUsedRanges = getRecentlyUsedRangesFactory(history);
|
||||
|
||||
const refreshInterval: RefreshInterval =
|
||||
globalState?.refreshInterval ?? timefilter.getRefreshInterval();
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
const setRefreshInterval = useCallback(
|
||||
debounce((refreshIntervalUpdate: RefreshInterval) => {
|
||||
setGlobalState('refreshInterval', refreshIntervalUpdate, true);
|
||||
}, 200),
|
||||
[setGlobalState]
|
||||
);
|
||||
|
||||
const [time, setTime] = useState(timefilter.getTime());
|
||||
const [recentlyUsedRanges, setRecentlyUsedRanges] = useState(getRecentlyUsedRanges());
|
||||
const [isAutoRefreshSelectorEnabled, setIsAutoRefreshSelectorEnabled] = useState(
|
||||
timefilter.isAutoRefreshSelectorEnabled()
|
||||
);
|
||||
const [isTimeRangeSelectorEnabled, setIsTimeRangeSelectorEnabled] = useState(
|
||||
timefilter.isTimeRangeSelectorEnabled()
|
||||
);
|
||||
|
||||
const dateFormat = config.get('dateFormat');
|
||||
const timePickerQuickRanges = config.get<TimePickerQuickRange[]>(
|
||||
UI_SETTINGS.TIMEPICKER_QUICK_RANGES
|
||||
);
|
||||
|
||||
const commonlyUsedRanges = useMemo(
|
||||
() =>
|
||||
timePickerQuickRanges.map(({ from, to, display }) => ({
|
||||
start: from,
|
||||
end: to,
|
||||
label: display,
|
||||
})),
|
||||
[timePickerQuickRanges]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const subscriptions = new Subscription();
|
||||
const refreshIntervalUpdate$ = timefilter.getRefreshIntervalUpdate$();
|
||||
if (refreshIntervalUpdate$ !== undefined) {
|
||||
subscriptions.add(
|
||||
refreshIntervalUpdate$.subscribe((r) => {
|
||||
setRefreshInterval(timefilter.getRefreshInterval());
|
||||
})
|
||||
);
|
||||
}
|
||||
const timeUpdate$ = timefilter.getTimeUpdate$();
|
||||
if (timeUpdate$ !== undefined) {
|
||||
subscriptions.add(
|
||||
timeUpdate$.subscribe((v) => {
|
||||
setTime(timefilter.getTime());
|
||||
})
|
||||
);
|
||||
}
|
||||
const enabledUpdated$ = timefilter.getEnabledUpdated$();
|
||||
if (enabledUpdated$ !== undefined) {
|
||||
subscriptions.add(
|
||||
enabledUpdated$.subscribe((w) => {
|
||||
setIsAutoRefreshSelectorEnabled(timefilter.isAutoRefreshSelectorEnabled());
|
||||
setIsTimeRangeSelectorEnabled(timefilter.isTimeRangeSelectorEnabled());
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return function cleanup() {
|
||||
subscriptions.unsubscribe();
|
||||
};
|
||||
}, [setRefreshInterval, timefilter]);
|
||||
|
||||
function updateFilter({ start, end }: Duration) {
|
||||
const newTime = { from: start, to: end };
|
||||
// Update timefilter for controllers listening for changes
|
||||
timefilter.setTime(newTime);
|
||||
setTime(newTime);
|
||||
setRecentlyUsedRanges(getRecentlyUsedRanges());
|
||||
}
|
||||
|
||||
function updateInterval({
|
||||
isPaused: pause,
|
||||
refreshInterval: value,
|
||||
}: {
|
||||
isPaused: boolean;
|
||||
refreshInterval: number;
|
||||
}) {
|
||||
setRefreshInterval({ pause, value });
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforce pause when it's set to false with 0 refresh interval.
|
||||
*/
|
||||
const isPaused = refreshInterval.pause || (!refreshInterval.pause && !refreshInterval.value);
|
||||
|
||||
return isAutoRefreshSelectorEnabled || isTimeRangeSelectorEnabled ? (
|
||||
<div className="mlNavigationMenu__datePickerWrapper">
|
||||
<EuiSuperDatePicker
|
||||
start={time.from}
|
||||
end={time.to}
|
||||
isPaused={isPaused}
|
||||
isAutoRefreshOnly={!isTimeRangeSelectorEnabled}
|
||||
refreshInterval={refreshInterval.value}
|
||||
onTimeChange={updateFilter}
|
||||
onRefresh={updateLastRefresh}
|
||||
onRefreshChange={updateInterval}
|
||||
recentlyUsedRanges={recentlyUsedRanges}
|
||||
dateFormat={dateFormat}
|
||||
commonlyUsedRanges={commonlyUsedRanges}
|
||||
/>
|
||||
</div>
|
||||
) : null;
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export { DatePickerWrapper } from './date_picker_wrapper';
|
|
@ -41,9 +41,12 @@ export const DocumentCountChart: FC<Props> = ({
|
|||
timeRangeLatest,
|
||||
interval,
|
||||
}) => {
|
||||
const seriesName = i18n.translate('xpack.ml.fieldDataCard.documentCountChart.seriesLabel', {
|
||||
defaultMessage: 'document count',
|
||||
});
|
||||
const seriesName = i18n.translate(
|
||||
'xpack.dataVisualizer.dataGrid.field.documentCountChart.seriesLabel',
|
||||
{
|
||||
defaultMessage: 'document count',
|
||||
}
|
||||
);
|
||||
|
||||
const xDomain = {
|
||||
min: timeRangeEarliest,
|
||||
|
@ -65,10 +68,11 @@ export const DocumentCountChart: FC<Props> = ({
|
|||
];
|
||||
}
|
||||
return chartPoints;
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [chartPoints, timeRangeEarliest, timeRangeLatest, interval]);
|
||||
|
||||
return (
|
||||
<div style={{ width: width ?? '100%' }} data-test-subj="mlFieldDataDocumentCountChart">
|
||||
<div style={{ width: width ?? '100%' }} data-test-subj="dataVisualizerDocumentCountChart">
|
||||
<Chart
|
||||
size={{
|
||||
width: '100%',
|
|
@ -6,9 +6,9 @@
|
|||
*/
|
||||
|
||||
import React, { FC } from 'react';
|
||||
import { DocumentCountChart, DocumentCountChartPoint } from '../document_count_chart';
|
||||
import { TotalCountHeader } from '../../total_count_header';
|
||||
import { FieldVisConfig, FileBasedFieldVisConfig } from '../../../../stats_table/types';
|
||||
import { DocumentCountChart, DocumentCountChartPoint } from './document_count_chart';
|
||||
import { FieldVisConfig, FileBasedFieldVisConfig } from '../stats_table/types';
|
||||
import { TotalCountHeader } from './total_count_header';
|
||||
|
||||
export interface Props {
|
||||
config?: FieldVisConfig | FileBasedFieldVisConfig;
|
|
@ -6,4 +6,3 @@
|
|||
*/
|
||||
|
||||
export { DocumentCountContent } from './document_count_content';
|
||||
export { NotInDocsContent } from './not_in_docs_content';
|
|
@ -12,15 +12,15 @@ import React from 'react';
|
|||
export const TotalCountHeader = ({ totalCount }: { totalCount: number }) => {
|
||||
return (
|
||||
<EuiFlexItem>
|
||||
<EuiText size="s" data-test-subj="mlDataVisualizerTotalDocCountHeader">
|
||||
<EuiText size="s" data-test-subj="dataVisualizerTotalDocCountHeader">
|
||||
<FormattedMessage
|
||||
id="xpack.ml.datavisualizer.searchPanel.totalDocCountLabel"
|
||||
id="xpack.dataVisualizer.searchPanel.totalDocCountLabel"
|
||||
defaultMessage="Total documents: {strongTotalCount}"
|
||||
values={{
|
||||
strongTotalCount: (
|
||||
<strong data-test-subj="mlDataVisualizerTotalDocCount">
|
||||
<strong data-test-subj="dataVisualizerTotalDocCount">
|
||||
<FormattedMessage
|
||||
id="xpack.ml.datavisualizer.searchPanel.totalDocCountNumber"
|
||||
id="xpack.dataVisualizer.searchPanel.totalDocCountNumber"
|
||||
defaultMessage="{totalCount, plural, one {#} other {#}}"
|
||||
values={{ totalCount }}
|
||||
/>
|
|
@ -8,22 +8,22 @@
|
|||
import React, { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { htmlIdGenerator } from '@elastic/eui';
|
||||
import { LayerDescriptor } from '../../../../../maps/common/descriptor_types';
|
||||
import { INITIAL_LOCATION } from '../../../../../maps/common/constants';
|
||||
import { LayerDescriptor } from '../../../../../../maps/common/descriptor_types';
|
||||
import { INITIAL_LOCATION } from '../../../../../../maps/common/constants';
|
||||
import {
|
||||
MapEmbeddable,
|
||||
MapEmbeddableInput,
|
||||
MapEmbeddableOutput,
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
} from '../../../../../maps/public/embeddable';
|
||||
import { MAP_SAVED_OBJECT_TYPE, RenderTooltipContentParams } from '../../../../../maps/public';
|
||||
} from '../../../../../../maps/public/embeddable';
|
||||
import { MAP_SAVED_OBJECT_TYPE, RenderTooltipContentParams } from '../../../../../../maps/public';
|
||||
import {
|
||||
EmbeddableFactory,
|
||||
ErrorEmbeddable,
|
||||
isErrorEmbeddable,
|
||||
ViewMode,
|
||||
} from '../../../../../../../src/plugins/embeddable/public';
|
||||
import { useFileDataVisualizerKibana } from '../../kibana_context';
|
||||
} from '../../../../../../../../src/plugins/embeddable/public';
|
||||
import { useDataVisualizerKibana } from '../../../kibana_context';
|
||||
|
||||
export function EmbeddedMapComponent({
|
||||
layerList,
|
||||
|
@ -41,7 +41,7 @@ export function EmbeddedMapComponent({
|
|||
|
||||
const {
|
||||
services: { embeddable: embeddablePlugin, maps: mapsPlugin },
|
||||
} = useFileDataVisualizerKibana();
|
||||
} = useDataVisualizerKibana();
|
||||
|
||||
const factory:
|
||||
| EmbeddableFactory<MapEmbeddableInput, MapEmbeddableOutput, MapEmbeddable>
|
||||
|
@ -143,7 +143,7 @@ export function EmbeddedMapComponent({
|
|||
|
||||
return (
|
||||
<div
|
||||
data-test-subj="mlEmbeddedMapContent"
|
||||
data-test-subj="dataVisualizerEmbeddedMapContent"
|
||||
className="embeddedMapContent"
|
||||
ref={embeddableRoot}
|
||||
/>
|
|
@ -23,7 +23,7 @@ export const ExamplesList: FC<Props> = ({ examples }) => {
|
|||
if (examples.length === 0) {
|
||||
examplesContent = (
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.fieldDataCard.examplesList.noExamplesMessage"
|
||||
id="xpack.dataVisualizer.dataGrid.field.examplesList.noExamplesMessage"
|
||||
defaultMessage="No examples were obtained for this field"
|
||||
/>
|
||||
);
|
||||
|
@ -41,10 +41,10 @@ export const ExamplesList: FC<Props> = ({ examples }) => {
|
|||
}
|
||||
|
||||
return (
|
||||
<div data-test-subj="mlFieldDataExamplesList">
|
||||
<div data-test-subj="dataVisualizerFieldDataExamplesList">
|
||||
<ExpandedRowFieldHeader>
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.fieldDataCard.examplesList.title"
|
||||
id="xpack.dataVisualizer.dataGrid.field.examplesList.title"
|
||||
defaultMessage="{numExamples, plural, one {Value} other {Examples}}"
|
||||
values={{
|
||||
numExamples: examples.length,
|
|
@ -16,7 +16,7 @@ import {
|
|||
NumberContent,
|
||||
} from '../stats_table/components/field_data_expanded_row';
|
||||
import { GeoPointContent } from './geo_point_content/geo_point_content';
|
||||
import { JOB_FIELD_TYPES } from '../../../../common';
|
||||
import { JOB_FIELD_TYPES } from '../../../../../common';
|
||||
import type { FileBasedFieldVisConfig } from '../stats_table/types/field_vis_config';
|
||||
|
||||
export const FileBasedDataVisualizerExpandedRow = ({ item }: { item: FileBasedFieldVisConfig }) => {
|
||||
|
@ -54,7 +54,7 @@ export const FileBasedDataVisualizerExpandedRow = ({ item }: { item: FileBasedFi
|
|||
return (
|
||||
<div
|
||||
className="dataVisualizerFieldExpandedRow"
|
||||
data-test-subj={`mlDataVisualizerFieldExpandedRow-${fieldName}`}
|
||||
data-test-subj={`dataVisualizerFieldExpandedRow-${fieldName}`}
|
||||
>
|
||||
{getCardContent()}
|
||||
</div>
|
|
@ -8,7 +8,7 @@
|
|||
import { Feature, Point } from 'geojson';
|
||||
import { euiPaletteColorBlind } from '@elastic/eui';
|
||||
import { DEFAULT_GEO_REGEX } from './geo_point_content';
|
||||
import { SOURCE_TYPES } from '../../../../../../maps/common/constants';
|
||||
import { SOURCE_TYPES } from '../../../../../../../maps/common/constants';
|
||||
|
||||
export const convertWKTGeoToLonLat = (
|
||||
value: string | number
|
|
@ -60,7 +60,7 @@ export const GeoPointContent: FC<FieldDataRowProps> = ({ config }) => {
|
|||
}
|
||||
}, [config]);
|
||||
return (
|
||||
<ExpandedRowContent dataTestSubj={'mlDVGeoPointContent'}>
|
||||
<ExpandedRowContent dataTestSubj={'dataVisualizerGeoPointContent'}>
|
||||
<DocumentStatsTable config={config} />
|
||||
{formattedResults && Array.isArray(formattedResults.examples) && (
|
||||
<EuiFlexItem>
|
||||
|
@ -70,7 +70,7 @@ export const GeoPointContent: FC<FieldDataRowProps> = ({ config }) => {
|
|||
{formattedResults && Array.isArray(formattedResults.layerList) && (
|
||||
<EuiFlexItem
|
||||
className={'dataVisualizerMapWrapper'}
|
||||
data-test-subj={'mlDataVisualizerEmbeddedMap'}
|
||||
data-test-subj={'dataVisualizerEmbeddedMap'}
|
||||
>
|
||||
<EmbeddedMapComponent layerList={formattedResults.layerList} />
|
||||
</EuiFlexItem>
|
|
@ -6,21 +6,20 @@
|
|||
*/
|
||||
|
||||
import React, { FC, useEffect, useState } from 'react';
|
||||
|
||||
import { EuiFlexItem } from '@elastic/eui';
|
||||
import { ExamplesList } from '../../../index_based/components/field_data_row/examples_list';
|
||||
import { MlEmbeddedMapComponent } from '../../../../components/ml_embedded_map';
|
||||
import { ML_JOB_FIELD_TYPES } from '../../../../../../common/constants/field_types';
|
||||
import { ES_GEO_FIELD_TYPE } from '../../../../../../../maps/common/constants';
|
||||
import { useMlKibana } from '../../../../contexts/kibana';
|
||||
import { DocumentStatsTable } from '../../../stats_table/components/field_data_expanded_row/document_stats';
|
||||
import { ExpandedRowContent } from '../../../stats_table/components/field_data_expanded_row/expanded_row_content';
|
||||
import type { CombinedQuery } from '../../common';
|
||||
import type { IndexPattern } from '../../../../../../../../../src/plugins/data/common/index_patterns/index_patterns';
|
||||
import type { LayerDescriptor } from '../../../../../../../maps/common/descriptor_types';
|
||||
import type { FieldVisConfig } from '../../../stats_table/types';
|
||||
import { IndexPattern } from '../../../../../../../../../src/plugins/data/common/index_patterns/index_patterns';
|
||||
import { CombinedQuery } from '../../../../index_data_visualizer/types/combined_query';
|
||||
import { ExpandedRowContent } from '../../stats_table/components/field_data_expanded_row/expanded_row_content';
|
||||
import { DocumentStatsTable } from '../../stats_table/components/field_data_expanded_row/document_stats';
|
||||
import { ExamplesList } from '../../examples_list';
|
||||
import { FieldVisConfig } from '../../stats_table/types';
|
||||
import { LayerDescriptor } from '../../../../../../../maps/common/descriptor_types';
|
||||
import { useDataVisualizerKibana } from '../../../../kibana_context';
|
||||
import { JOB_FIELD_TYPES } from '../../../../../../common';
|
||||
import { ES_GEO_FIELD_TYPE } from '../../../../../../../maps/common';
|
||||
import { EmbeddedMapComponent } from '../../embedded_map';
|
||||
|
||||
export const GeoPointContent: FC<{
|
||||
export const GeoPointContentWithMap: FC<{
|
||||
config: FieldVisConfig;
|
||||
indexPattern: IndexPattern | undefined;
|
||||
combinedQuery: CombinedQuery;
|
||||
|
@ -29,7 +28,7 @@ export const GeoPointContent: FC<{
|
|||
const [layerList, setLayerList] = useState<LayerDescriptor[]>([]);
|
||||
const {
|
||||
services: { maps: mapsPlugin },
|
||||
} = useMlKibana();
|
||||
} = useDataVisualizerKibana();
|
||||
|
||||
// Update the layer list with updated geo points upon refresh
|
||||
useEffect(() => {
|
||||
|
@ -38,8 +37,7 @@ export const GeoPointContent: FC<{
|
|||
indexPattern?.id !== undefined &&
|
||||
config !== undefined &&
|
||||
config.fieldName !== undefined &&
|
||||
(config.type === ML_JOB_FIELD_TYPES.GEO_POINT ||
|
||||
config.type === ML_JOB_FIELD_TYPES.GEO_SHAPE)
|
||||
(config.type === JOB_FIELD_TYPES.GEO_POINT || config.type === JOB_FIELD_TYPES.GEO_SHAPE)
|
||||
) {
|
||||
const params = {
|
||||
indexPatternId: indexPattern.id,
|
||||
|
@ -59,18 +57,19 @@ export const GeoPointContent: FC<{
|
|||
}
|
||||
}
|
||||
updateIndexPatternSearchLayer();
|
||||
}, [indexPattern, config.fieldName, combinedQuery]);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [indexPattern, combinedQuery, config, mapsPlugin]);
|
||||
|
||||
if (stats?.examples === undefined) return null;
|
||||
return (
|
||||
<ExpandedRowContent dataTestSubj={'mlDVIndexBasedMapContent'}>
|
||||
<ExpandedRowContent dataTestSubj={'dataVisualizerIndexBasedMapContent'}>
|
||||
<DocumentStatsTable config={config} />
|
||||
|
||||
<EuiFlexItem style={{ maxWidth: '50%' }}>
|
||||
<ExamplesList examples={stats.examples} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem className={'mlDataVisualizerMapWrapper'}>
|
||||
<MlEmbeddedMapComponent layerList={layerList} />
|
||||
<EuiFlexItem className={'dataVisualizerMapWrapper'}>
|
||||
<EmbeddedMapComponent layerList={layerList} />
|
||||
</EuiFlexItem>
|
||||
</ExpandedRowContent>
|
||||
);
|
|
@ -5,4 +5,4 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export { FileDataVisualizer } from './file_datavisualizer';
|
||||
export { GeoPointContentWithMap } from './geo_point_content_with_map';
|
|
@ -6,10 +6,8 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { ML_JOB_FIELD_TYPES } from '../../../../../../common/constants/field_types';
|
||||
import { LoadingIndicator } from '../field_data_row/loading_indicator';
|
||||
import { NotInDocsContent } from '../field_data_row/content_types';
|
||||
import { GeoPointContentWithMap } from './geo_point_content_with_map';
|
||||
import { JOB_FIELD_TYPES } from '../../../../../common';
|
||||
import {
|
||||
BooleanContent,
|
||||
DateContent,
|
||||
|
@ -18,11 +16,12 @@ import {
|
|||
NumberContent,
|
||||
OtherContent,
|
||||
TextContent,
|
||||
} from '../../../stats_table/components/field_data_expanded_row';
|
||||
import { GeoPointContent } from './geo_point_content';
|
||||
import type { CombinedQuery } from '../../common';
|
||||
import type { IndexPattern } from '../../../../../../../../../src/plugins/data/common/index_patterns/index_patterns';
|
||||
import type { FieldVisConfig } from '../../../stats_table/types';
|
||||
} from '../stats_table/components/field_data_expanded_row';
|
||||
import { NotInDocsContent } from '../not_in_docs_content';
|
||||
import { FieldVisConfig } from '../stats_table/types';
|
||||
import { IndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns/index_patterns';
|
||||
import { CombinedQuery } from '../../../index_data_visualizer/types/combined_query';
|
||||
import { LoadingIndicator } from '../loading_indicator';
|
||||
|
||||
export const IndexBasedDataVisualizerExpandedRow = ({
|
||||
item,
|
||||
|
@ -42,32 +41,32 @@ export const IndexBasedDataVisualizerExpandedRow = ({
|
|||
}
|
||||
|
||||
switch (type) {
|
||||
case ML_JOB_FIELD_TYPES.NUMBER:
|
||||
case JOB_FIELD_TYPES.NUMBER:
|
||||
return <NumberContent config={config} />;
|
||||
|
||||
case ML_JOB_FIELD_TYPES.BOOLEAN:
|
||||
case JOB_FIELD_TYPES.BOOLEAN:
|
||||
return <BooleanContent config={config} />;
|
||||
|
||||
case ML_JOB_FIELD_TYPES.DATE:
|
||||
case JOB_FIELD_TYPES.DATE:
|
||||
return <DateContent config={config} />;
|
||||
|
||||
case ML_JOB_FIELD_TYPES.GEO_POINT:
|
||||
case ML_JOB_FIELD_TYPES.GEO_SHAPE:
|
||||
case JOB_FIELD_TYPES.GEO_POINT:
|
||||
case JOB_FIELD_TYPES.GEO_SHAPE:
|
||||
return (
|
||||
<GeoPointContent
|
||||
<GeoPointContentWithMap
|
||||
config={config}
|
||||
indexPattern={indexPattern}
|
||||
combinedQuery={combinedQuery}
|
||||
/>
|
||||
);
|
||||
|
||||
case ML_JOB_FIELD_TYPES.IP:
|
||||
case JOB_FIELD_TYPES.IP:
|
||||
return <IpContent config={config} />;
|
||||
|
||||
case ML_JOB_FIELD_TYPES.KEYWORD:
|
||||
case JOB_FIELD_TYPES.KEYWORD:
|
||||
return <KeywordContent config={config} />;
|
||||
|
||||
case ML_JOB_FIELD_TYPES.TEXT:
|
||||
case JOB_FIELD_TYPES.TEXT:
|
||||
return <TextContent config={config} />;
|
||||
|
||||
default:
|
||||
|
@ -77,8 +76,8 @@ export const IndexBasedDataVisualizerExpandedRow = ({
|
|||
|
||||
return (
|
||||
<div
|
||||
className="mlDataVisualizerFieldExpandedRow"
|
||||
data-test-subj={`mlDataVisualizerFieldExpandedRow-${fieldName}`}
|
||||
className="dataVisualizerFieldExpandedRow"
|
||||
data-test-subj={`dataVisualizerFieldExpandedRow-${fieldName}`}
|
||||
>
|
||||
{loading === true ? <LoadingIndicator /> : getCardContent()}
|
||||
</div>
|
|
@ -17,7 +17,7 @@ export const ExperimentalBadge: FC<{ tooltipContent: string }> = ({ tooltipConte
|
|||
className="experimental-badge"
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.experimentalBadge.experimentalLabel"
|
||||
id="xpack.dataVisualizer.experimentalBadge.experimentalLabel"
|
||||
defaultMessage="Experimental"
|
||||
/>
|
||||
}
|
|
@ -8,14 +8,11 @@
|
|||
import { EuiFlexGroup, EuiFlexItem, EuiSwitch } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React, { FC } from 'react';
|
||||
import {
|
||||
MetricFieldsCount,
|
||||
TotalFieldsCount,
|
||||
} from '../../../stats_table/components/field_count_stats';
|
||||
import type {
|
||||
TotalFieldsCountProps,
|
||||
MetricFieldsCountProps,
|
||||
} from '../../../stats_table/components/field_count_stats';
|
||||
TotalFieldsCountProps,
|
||||
} from '../stats_table/components/field_count_stats';
|
||||
import { MetricFieldsCount, TotalFieldsCount } from '../stats_table/components/field_count_stats';
|
||||
|
||||
interface Props extends TotalFieldsCountProps, MetricFieldsCountProps {
|
||||
showEmptyFields: boolean;
|
||||
|
@ -32,16 +29,16 @@ export const FieldCountPanel: FC<Props> = ({
|
|||
alignItems="center"
|
||||
gutterSize="xs"
|
||||
style={{ marginLeft: 4 }}
|
||||
data-test-subj="mlDataVisualizerFieldCountPanel"
|
||||
data-test-subj="dataVisualizerFieldCountPanel"
|
||||
>
|
||||
<TotalFieldsCount fieldsCountStats={fieldsCountStats} />
|
||||
<MetricFieldsCount metricsStats={metricsStats} />
|
||||
<EuiFlexItem>
|
||||
<EuiSwitch
|
||||
data-test-subj="mlDataVisualizerShowEmptyFieldsSwitch"
|
||||
data-test-subj="dataVisualizerShowEmptyFieldsSwitch"
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="xpack.ml.dataVisualizer.searchPanel.showEmptyFields"
|
||||
id="xpack.dataVisualizer.searchPanel.showEmptyFields"
|
||||
defaultMessage="Show empty fields"
|
||||
/>
|
||||
}
|
|
@ -8,28 +8,24 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { Action } from '@elastic/eui/src/components/basic_table/action_types';
|
||||
import { getCompatibleLensDataType, getLensAttributes } from './lens_utils';
|
||||
import type { CombinedQuery } from '../../../common';
|
||||
import type { IIndexPattern } from '../../../../../../../../../../src/plugins/data/common/index_patterns';
|
||||
import type { LensPublicStart } from '../../../../../../../../lens/public';
|
||||
import type { FieldVisConfig } from '../../../../stats_table/types';
|
||||
|
||||
import { IndexPattern } from '../../../../../../../../../src/plugins/data/common/index_patterns/index_patterns';
|
||||
import { CombinedQuery } from '../../../../index_data_visualizer/types/combined_query';
|
||||
import { FieldVisConfig } from '../../stats_table/types';
|
||||
import { LensPublicStart } from '../../../../../../../lens/public';
|
||||
export function getActions(
|
||||
indexPattern: IIndexPattern,
|
||||
indexPattern: IndexPattern,
|
||||
lensPlugin: LensPublicStart,
|
||||
combinedQuery: CombinedQuery
|
||||
): Array<Action<FieldVisConfig>> {
|
||||
const canUseLensEditor = lensPlugin.canUseEditor();
|
||||
return [
|
||||
{
|
||||
name: i18n.translate('xpack.ml.dataVisualizer.indexBasedDataGrid.exploreInLensTitle', {
|
||||
name: i18n.translate('xpack.dataVisualizer.index.dataGrid.exploreInLensTitle', {
|
||||
defaultMessage: 'Explore in Lens',
|
||||
}),
|
||||
description: i18n.translate('xpack.dataVisualizer.index.dataGrid.exploreInLensDescription', {
|
||||
defaultMessage: 'Explore in Lens',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.ml.dataVisualizer.indexBasedDataGrid.exploreInLensDescription',
|
||||
{
|
||||
defaultMessage: 'Explore in Lens',
|
||||
}
|
||||
),
|
||||
type: 'icon',
|
||||
icon: 'lensApp',
|
||||
available: (item: FieldVisConfig) =>
|
||||
|
@ -38,12 +34,12 @@ export function getActions(
|
|||
const lensAttributes = getLensAttributes(indexPattern, combinedQuery, item);
|
||||
if (lensAttributes) {
|
||||
lensPlugin.navigateToPrefilledEditor({
|
||||
id: `ml-dataVisualizer-${item.fieldName}`,
|
||||
id: `dataVisualizer-${item.fieldName}`,
|
||||
attributes: lensAttributes,
|
||||
});
|
||||
}
|
||||
},
|
||||
'data-test-subj': 'mlActionButtonViewInLens',
|
||||
'data-test-subj': 'dataVisualizerActionViewInLensButton',
|
||||
},
|
||||
];
|
||||
}
|
|
@ -6,25 +6,28 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ML_JOB_FIELD_TYPES } from '../../../../../../../common/constants/field_types';
|
||||
import type { TypedLensByValueInput } from '../../../../../../../../lens/public';
|
||||
import type { FieldVisConfig } from '../../../../stats_table/types';
|
||||
import type { IndexPatternColumn, XYLayerConfig } from '../../../../../../../../lens/public';
|
||||
import type { CombinedQuery } from '../../../common';
|
||||
import type { IIndexPattern } from '../../../../../../../../../../src/plugins/data/common/index_patterns';
|
||||
import type { IndexPattern } from '../../../../../../../../../src/plugins/data/common/index_patterns/index_patterns';
|
||||
import type { CombinedQuery } from '../../../../index_data_visualizer/types/combined_query';
|
||||
import type {
|
||||
IndexPatternColumn,
|
||||
TypedLensByValueInput,
|
||||
XYLayerConfig,
|
||||
} from '../../../../../../../lens/public';
|
||||
import { FieldVisConfig } from '../../stats_table/types';
|
||||
import { JOB_FIELD_TYPES } from '../../../../../../common';
|
||||
interface ColumnsAndLayer {
|
||||
columns: Record<string, IndexPatternColumn>;
|
||||
layer: XYLayerConfig;
|
||||
}
|
||||
|
||||
const TOP_VALUES_LABEL = i18n.translate('xpack.ml.dataVisualizer.lensChart.topValuesLabel', {
|
||||
const TOP_VALUES_LABEL = i18n.translate('xpack.dataVisualizer.index.lensChart.topValuesLabel', {
|
||||
defaultMessage: 'Top values',
|
||||
});
|
||||
const COUNT = i18n.translate('xpack.ml.dataVisualizer.lensChart.countLabel', {
|
||||
const COUNT = i18n.translate('xpack.dataVisualizer.index.lensChart.countLabel', {
|
||||
defaultMessage: 'Count',
|
||||
});
|
||||
|
||||
export function getNumberSettings(item: FieldVisConfig, defaultIndexPattern: IIndexPattern) {
|
||||
export function getNumberSettings(item: FieldVisConfig, defaultIndexPattern: IndexPattern) {
|
||||
// if index has no timestamp field
|
||||
if (defaultIndexPattern.timeFieldName === undefined) {
|
||||
const columns: Record<string, IndexPatternColumn> = {
|
||||
|
@ -62,7 +65,7 @@ export function getNumberSettings(item: FieldVisConfig, defaultIndexPattern: IIn
|
|||
col2: {
|
||||
dataType: 'number',
|
||||
isBucketed: false,
|
||||
label: i18n.translate('xpack.ml.dataVisualizer.lensChart.averageOfLabel', {
|
||||
label: i18n.translate('xpack.dataVisualizer.index.lensChart.averageOfLabel', {
|
||||
defaultMessage: 'Average of {fieldName}',
|
||||
values: { fieldName: item.fieldName },
|
||||
}),
|
||||
|
@ -186,19 +189,19 @@ export function getBooleanSettings(item: FieldVisConfig) {
|
|||
export function getCompatibleLensDataType(type: FieldVisConfig['type']): string | undefined {
|
||||
let lensType: string | undefined;
|
||||
switch (type) {
|
||||
case ML_JOB_FIELD_TYPES.KEYWORD:
|
||||
case JOB_FIELD_TYPES.KEYWORD:
|
||||
lensType = 'string';
|
||||
break;
|
||||
case ML_JOB_FIELD_TYPES.DATE:
|
||||
case JOB_FIELD_TYPES.DATE:
|
||||
lensType = 'date';
|
||||
break;
|
||||
case ML_JOB_FIELD_TYPES.NUMBER:
|
||||
case JOB_FIELD_TYPES.NUMBER:
|
||||
lensType = 'number';
|
||||
break;
|
||||
case ML_JOB_FIELD_TYPES.IP:
|
||||
case JOB_FIELD_TYPES.IP:
|
||||
lensType = 'ip';
|
||||
break;
|
||||
case ML_JOB_FIELD_TYPES.BOOLEAN:
|
||||
case JOB_FIELD_TYPES.BOOLEAN:
|
||||
lensType = 'string';
|
||||
break;
|
||||
default:
|
||||
|
@ -210,20 +213,20 @@ export function getCompatibleLensDataType(type: FieldVisConfig['type']): string
|
|||
function getColumnsAndLayer(
|
||||
fieldType: FieldVisConfig['type'],
|
||||
item: FieldVisConfig,
|
||||
defaultIndexPattern: IIndexPattern
|
||||
defaultIndexPattern: IndexPattern
|
||||
): ColumnsAndLayer | undefined {
|
||||
if (item.fieldName === undefined) return;
|
||||
|
||||
if (fieldType === ML_JOB_FIELD_TYPES.DATE) {
|
||||
if (fieldType === JOB_FIELD_TYPES.DATE) {
|
||||
return getDateSettings(item);
|
||||
}
|
||||
if (fieldType === ML_JOB_FIELD_TYPES.NUMBER) {
|
||||
if (fieldType === JOB_FIELD_TYPES.NUMBER) {
|
||||
return getNumberSettings(item, defaultIndexPattern);
|
||||
}
|
||||
if (fieldType === ML_JOB_FIELD_TYPES.IP || fieldType === ML_JOB_FIELD_TYPES.KEYWORD) {
|
||||
if (fieldType === JOB_FIELD_TYPES.IP || fieldType === JOB_FIELD_TYPES.KEYWORD) {
|
||||
return getKeywordSettings(item);
|
||||
}
|
||||
if (fieldType === ML_JOB_FIELD_TYPES.BOOLEAN) {
|
||||
if (fieldType === JOB_FIELD_TYPES.BOOLEAN) {
|
||||
return getBooleanSettings(item);
|
||||
}
|
||||
}
|
||||
|
@ -231,7 +234,7 @@ function getColumnsAndLayer(
|
|||
// currently only supports the following types:
|
||||
// 'document' | 'string' | 'number' | 'date' | 'boolean' | 'ip'
|
||||
export function getLensAttributes(
|
||||
defaultIndexPattern: IIndexPattern | undefined,
|
||||
defaultIndexPattern: IndexPattern | undefined,
|
||||
combinedQuery: CombinedQuery,
|
||||
item: FieldVisConfig
|
||||
): TypedLensByValueInput['attributes'] | undefined {
|
||||
|
@ -244,7 +247,7 @@ export function getLensAttributes(
|
|||
|
||||
return {
|
||||
visualizationType: 'lnsXY',
|
||||
title: i18n.translate('xpack.ml.dataVisualizer.lensChart.chartTitle', {
|
||||
title: i18n.translate('xpack.dataVisualizer.index.lensChart.chartTitle', {
|
||||
defaultMessage: 'Lens for {fieldName}',
|
||||
values: { fieldName: item.fieldName },
|
||||
}),
|
|
@ -24,26 +24,20 @@ export const FileBasedNumberContentPreview = ({ config }: { config: FileBasedFie
|
|||
<EuiFlexGroup gutterSize="xs">
|
||||
<EuiFlexItem>
|
||||
<b>
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.fieldStatsCard.minTitle"
|
||||
defaultMessage="min"
|
||||
/>
|
||||
<FormattedMessage id="xpack.dataVisualizer.fieldStats.minTitle" defaultMessage="min" />
|
||||
</b>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<b>
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.fieldStatsCard.medianTitle"
|
||||
id="xpack.dataVisualizer.fieldStats.medianTitle"
|
||||
defaultMessage="median"
|
||||
/>
|
||||
</b>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<b>
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.fieldStatsCard.maxTitle"
|
||||
defaultMessage="max"
|
||||
/>
|
||||
<FormattedMessage id="xpack.dataVisualizer.fieldStats.maxTitle" defaultMessage="max" />
|
||||
</b>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
|
@ -26,7 +26,7 @@ export const DataVisualizerFieldNamesFilter: FC<Props> = ({
|
|||
}) => {
|
||||
const fieldNameTitle = useMemo(
|
||||
() =>
|
||||
i18n.translate('xpack.fileDataVisualizer.fieldNameSelect', {
|
||||
i18n.translate('xpack.dataVisualizer.fieldNameSelect', {
|
||||
defaultMessage: 'Field name',
|
||||
}),
|
||||
[]
|
||||
|
@ -42,7 +42,7 @@ export const DataVisualizerFieldNamesFilter: FC<Props> = ({
|
|||
options={options}
|
||||
onChange={setVisibleFieldNames}
|
||||
checkedOptions={visibleFieldNames}
|
||||
dataTestSubj={'mlDataVisualizerFieldNameSelect'}
|
||||
dataTestSubj={'dataVisualizerFieldNameSelect'}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
|||
import { mount, shallow } from 'enzyme';
|
||||
|
||||
import { FieldTypeIcon } from './field_type_icon';
|
||||
import { JOB_FIELD_TYPES } from '../../../../common';
|
||||
import { JOB_FIELD_TYPES } from '../../../../../common';
|
||||
|
||||
describe('FieldTypeIcon', () => {
|
||||
test(`render component when type matches a field type`, () => {
|
|
@ -12,8 +12,8 @@ import { EuiToken, EuiToolTip } from '@elastic/eui';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { getJobTypeAriaLabel } from '../../util/field_types_utils';
|
||||
import { JOB_FIELD_TYPES } from '../../../../common';
|
||||
import type { JobFieldType } from '../../../../common';
|
||||
import { JOB_FIELD_TYPES } from '../../../../../common';
|
||||
import type { JobFieldType } from '../../../../../common';
|
||||
|
||||
interface FieldTypeIconProps {
|
||||
tooltipEnabled: boolean;
|
||||
|
@ -91,7 +91,7 @@ export const FieldTypeIcon: FC<FieldTypeIconProps> = ({
|
|||
return (
|
||||
<EuiToolTip
|
||||
position="left"
|
||||
content={i18n.translate('xpack.fileDataVisualizer.fieldTypeIcon.fieldTypeTooltip', {
|
||||
content={i18n.translate('xpack.dataVisualizer.fieldTypeIcon.fieldTypeTooltip', {
|
||||
defaultMessage: '{type} type',
|
||||
values: { type },
|
||||
})}
|
|
@ -14,7 +14,7 @@ import type {
|
|||
FileBasedUnknownFieldVisConfig,
|
||||
} from '../stats_table/types/field_vis_config';
|
||||
import { FieldTypeIcon } from '../field_type_icon';
|
||||
import { JOB_FIELD_TYPES } from '../../../../common';
|
||||
import { JOB_FIELD_TYPES } from '../../../../../common';
|
||||
|
||||
const JOB_FIELD_TYPES_OPTIONS = {
|
||||
[JOB_FIELD_TYPES.BOOLEAN]: { name: 'Boolean', icon: 'tokenBoolean' },
|
||||
|
@ -41,7 +41,7 @@ export const DataVisualizerFieldTypesFilter: FC<Props> = ({
|
|||
}) => {
|
||||
const fieldNameTitle = useMemo(
|
||||
() =>
|
||||
i18n.translate('xpack.fileDataVisualizer.fieldTypeSelect', {
|
||||
i18n.translate('xpack.dataVisualizer.fieldTypeSelect', {
|
||||
defaultMessage: 'Field type',
|
||||
}),
|
||||
[]
|
||||
|
@ -87,7 +87,7 @@ export const DataVisualizerFieldTypesFilter: FC<Props> = ({
|
|||
options={options}
|
||||
onChange={setVisibleFieldTypes}
|
||||
checkedOptions={visibleFieldTypes}
|
||||
dataTestSubj={'mlDataVisualizerFieldTypeSelect'}
|
||||
dataTestSubj={'dataVisualizerFieldTypeSelect'}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -5,10 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { FindFileStructureResponse } from '../../../../../file_upload/common';
|
||||
import { FindFileStructureResponse } from '../../../../../../file_upload/common';
|
||||
import { getFieldNames, getSupportedFieldType } from './get_field_names';
|
||||
import { FileBasedFieldVisConfig } from '../stats_table/types';
|
||||
import { JOB_FIELD_TYPES } from '../../../../common';
|
||||
import { JOB_FIELD_TYPES } from '../../../../../common';
|
||||
import { roundToDecimalPlace } from '../utils';
|
||||
|
||||
export function createFields(results: FindFileStructureResponse) {
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
import React, { useMemo, FC, useState } from 'react';
|
||||
import { EuiFlexGroup, EuiSpacer } from '@elastic/eui';
|
||||
import type { FindFileStructureResponse } from '../../../../../file_upload/common';
|
||||
import type { DataVisualizerTableState } from '../../../../common';
|
||||
import type { FindFileStructureResponse } from '../../../../../../file_upload/common';
|
||||
import type { DataVisualizerTableState } from '../../../../../common';
|
||||
import { DataVisualizerTable, ItemIdToExpandedRowMap } from '../stats_table';
|
||||
import type { FileBasedFieldVisConfig } from '../stats_table/types/field_vis_config';
|
||||
import { FileBasedDataVisualizerExpandedRow } from '../expanded_row';
|
||||
|
@ -85,14 +85,14 @@ export const FieldsStatsGrid: FC<Props> = ({ results }) => {
|
|||
alignItems="center"
|
||||
gutterSize="xs"
|
||||
style={{ marginLeft: 4 }}
|
||||
data-test-subj="mlDataVisualizerFieldCountPanel"
|
||||
data-test-subj="dataVisualizerFieldCountPanel"
|
||||
>
|
||||
<TotalFieldsCount fieldsCountStats={fieldsCountStats} />
|
||||
<MetricFieldsCount metricsStats={metricsStats} />
|
||||
|
||||
<EuiFlexGroup
|
||||
gutterSize="xs"
|
||||
data-test-subj="mlDataVisualizerFieldCountPanel"
|
||||
data-test-subj="dataVisualizerFieldCountPanel"
|
||||
justifyContent={'flexEnd'}
|
||||
>
|
||||
<DataVisualizerFieldNamesFilter
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { JOB_FIELD_TYPES } from '../../../../common';
|
||||
import { JOB_FIELD_TYPES } from '../../../../../common';
|
||||
import type {
|
||||
FileBasedFieldVisConfig,
|
||||
FileBasedUnknownFieldVisConfig,
|
|
@ -6,10 +6,10 @@
|
|||
*/
|
||||
|
||||
import { difference } from 'lodash';
|
||||
import { ES_FIELD_TYPES } from '../../../../../../../src/plugins/data/common';
|
||||
import type { FindFileStructureResponse } from '../../../../../file_upload/common';
|
||||
import type { JobFieldType } from '../../../../common';
|
||||
import { JOB_FIELD_TYPES } from '../../../../common';
|
||||
import { ES_FIELD_TYPES } from '../../../../../../../../src/plugins/data/common';
|
||||
import type { FindFileStructureResponse } from '../../../../../../file_upload/common';
|
||||
import type { JobFieldType } from '../../../../../common';
|
||||
import { JOB_FIELD_TYPES } from '../../../../../common';
|
||||
export function getFieldNames(results: FindFileStructureResponse) {
|
||||
const { mappings, field_stats: fieldStats, column_names: columnNames } = results;
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FindFileStructureResponse } from '../../../../../file_upload/common';
|
||||
import { FindFileStructureResponse } from '../../../../../../file_upload/common';
|
||||
|
||||
export function createFilebeatConfig(
|
||||
index: string,
|
||||
|
@ -36,7 +36,7 @@ export function createFilebeatConfig(
|
|||
}
|
||||
|
||||
function getPaths() {
|
||||
const txt = i18n.translate('xpack.fileDataVisualizer.fileBeatConfig.paths', {
|
||||
const txt = i18n.translate('xpack.dataVisualizer.fileBeatConfig.paths', {
|
||||
defaultMessage: 'add path to your files here',
|
||||
});
|
||||
return [' paths:', ` - '<${txt}>'`];
|
|
@ -22,8 +22,8 @@ import {
|
|||
EuiCopy,
|
||||
} from '@elastic/eui';
|
||||
import { createFilebeatConfig } from './filebeat_config';
|
||||
import { useFileDataVisualizerKibana } from '../../kibana_context'; // copy context?
|
||||
import { FindFileStructureResponse } from '../../../../../file_upload/common';
|
||||
import { useDataVisualizerKibana } from '../../../kibana_context'; // copy context?
|
||||
import { FindFileStructureResponse } from '../../../../../../file_upload/common';
|
||||
|
||||
export enum EDITOR_MODE {
|
||||
HIDDEN,
|
||||
|
@ -48,7 +48,7 @@ export const FilebeatConfigFlyout: FC<Props> = ({
|
|||
const [username, setUsername] = useState<string | null>(null);
|
||||
const {
|
||||
services: { security },
|
||||
} = useFileDataVisualizerKibana();
|
||||
} = useDataVisualizerKibana();
|
||||
|
||||
useEffect(() => {
|
||||
if (security !== undefined) {
|
||||
|
@ -75,7 +75,7 @@ export const FilebeatConfigFlyout: FC<Props> = ({
|
|||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty iconType="cross" onClick={closeFlyout} flush="left">
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.fileBeatConfigFlyout.closeButton"
|
||||
id="xpack.dataVisualizer.fileBeatConfigFlyout.closeButton"
|
||||
defaultMessage="Close"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
|
@ -85,7 +85,7 @@ export const FilebeatConfigFlyout: FC<Props> = ({
|
|||
{(copy) => (
|
||||
<EuiButton onClick={copy}>
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.fileBeatConfigFlyout.copyButton"
|
||||
id="xpack.dataVisualizer.fileBeatConfigFlyout.copyButton"
|
||||
defaultMessage="Copy to clipboard"
|
||||
/>
|
||||
</EuiButton>
|
||||
|
@ -108,7 +108,7 @@ const Contents: FC<{
|
|||
<EuiTitle size="s">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.resultsLinks.fileBeatConfigTitle"
|
||||
id="xpack.dataVisualizer.file.resultsLinks.fileBeatConfigTitle"
|
||||
defaultMessage="Filebeat configuration"
|
||||
/>
|
||||
</h5>
|
||||
|
@ -116,14 +116,14 @@ const Contents: FC<{
|
|||
<EuiSpacer size="s" />
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.resultsLinks.fileBeatConfigTopText1"
|
||||
id="xpack.dataVisualizer.file.resultsLinks.fileBeatConfigTopText1"
|
||||
defaultMessage="Additional data can be uploaded to the {index} index using Filebeat."
|
||||
values={{ index: <EuiCode>{index}</EuiCode> }}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.resultsLinks.fileBeatConfigTopText2"
|
||||
id="xpack.dataVisualizer.file.resultsLinks.fileBeatConfigTopText2"
|
||||
defaultMessage="Modify {filebeatYml} to set the connection information:"
|
||||
values={{ filebeatYml: <EuiCode>filebeat.yml</EuiCode> }}
|
||||
/>
|
||||
|
@ -137,7 +137,7 @@ const Contents: FC<{
|
|||
<p>
|
||||
{username === null ? (
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.resultsLinks.fileBeatConfigBottomTextNoUsername"
|
||||
id="xpack.dataVisualizer.file.resultsLinks.fileBeatConfigBottomTextNoUsername"
|
||||
defaultMessage="Where {esUrl} is the URL of Elasticsearch."
|
||||
values={{
|
||||
esUrl: <EuiCode>{'<es_url>'}</EuiCode>,
|
||||
|
@ -145,7 +145,7 @@ const Contents: FC<{
|
|||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.resultsLinks.fileBeatConfigBottomText"
|
||||
id="xpack.dataVisualizer.file.resultsLinks.fileBeatConfigBottomText"
|
||||
defaultMessage="Where {password} is the password of the {user} user, {esUrl} is the URL of Elasticsearch."
|
||||
values={{
|
||||
user: <EuiCode>{username}</EuiCode>,
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { FC, useEffect } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useDataVisualizerKibana } from '../../../kibana_context';
|
||||
|
||||
interface HelpMenuProps {
|
||||
docLink: string;
|
||||
}
|
||||
|
||||
// Component for adding a documentation link to the help menu
|
||||
export const HelpMenu: FC<HelpMenuProps> = React.memo(({ docLink }) => {
|
||||
const { chrome } = useDataVisualizerKibana().services;
|
||||
|
||||
useEffect(() => {
|
||||
chrome.setHelpExtension({
|
||||
appName: i18n.translate('xpack.dataVisualizer.chrome.help.appName', {
|
||||
defaultMessage: 'Data Visualizer',
|
||||
}),
|
||||
links: [
|
||||
{
|
||||
href: docLink,
|
||||
linkType: 'documentation',
|
||||
},
|
||||
],
|
||||
});
|
||||
}, [chrome, docLink]);
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
HelpMenu.displayName = 'HelpMenu';
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export { HelpMenu } from './help_menu';
|
|
@ -5,4 +5,4 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export { TopValues } from './top_values';
|
||||
export { LinkCard } from './link_card';
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { FC, ReactElement } from 'react';
|
||||
|
||||
import {
|
||||
EuiIcon,
|
||||
IconType,
|
||||
EuiText,
|
||||
EuiTitle,
|
||||
EuiFlexItem,
|
||||
EuiFlexGroup,
|
||||
EuiPanel,
|
||||
EuiLink,
|
||||
} from '@elastic/eui';
|
||||
|
||||
interface Props {
|
||||
icon: IconType | ReactElement;
|
||||
iconAreaLabel?: string;
|
||||
title: any;
|
||||
description: any;
|
||||
href?: string;
|
||||
onClick?: () => void;
|
||||
isDisabled?: boolean;
|
||||
'data-test-subj'?: string;
|
||||
}
|
||||
|
||||
// Component for rendering a card which links to the Create Job page, displaying an
|
||||
// icon, card title, description and link.
|
||||
export const LinkCard: FC<Props> = ({
|
||||
icon,
|
||||
iconAreaLabel,
|
||||
title,
|
||||
description,
|
||||
onClick,
|
||||
href,
|
||||
isDisabled,
|
||||
'data-test-subj': dateTestSubj,
|
||||
}) => {
|
||||
const linkHrefAndOnClickProps = {
|
||||
...(href ? { href } : {}),
|
||||
...(onClick ? { onClick } : {}),
|
||||
};
|
||||
return (
|
||||
<EuiPanel style={{ cursor: isDisabled ? 'not-allowed' : undefined }}>
|
||||
<EuiLink
|
||||
style={{
|
||||
display: 'block',
|
||||
pointerEvents: isDisabled ? 'none' : undefined,
|
||||
background: 'transparent',
|
||||
outline: 'none',
|
||||
}}
|
||||
data-test-subj={dateTestSubj}
|
||||
color="subdued"
|
||||
{...linkHrefAndOnClickProps}
|
||||
>
|
||||
<EuiFlexGroup gutterSize="l" responsive={true}>
|
||||
<EuiFlexItem grow={false} style={{ paddingTop: '8px' }}>
|
||||
{typeof icon === 'string' ? (
|
||||
<EuiIcon size="xl" type={icon} aria-label={iconAreaLabel} />
|
||||
) : (
|
||||
icon
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiTitle size="s">
|
||||
<h3>{title}</h3>
|
||||
</EuiTitle>
|
||||
<EuiText color="subdued">
|
||||
<p>{description}</p>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiLink>
|
||||
</EuiPanel>
|
||||
);
|
||||
};
|
|
@ -10,7 +10,6 @@ import React, { FC, Fragment } from 'react';
|
|||
import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner, EuiSpacer, EuiText } from '@elastic/eui';
|
||||
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
export const LoadingIndicator: FC = () => (
|
||||
<Fragment>
|
||||
<EuiSpacer size="xxl" />
|
||||
|
@ -22,7 +21,10 @@ export const LoadingIndicator: FC = () => (
|
|||
<EuiFlexGroup justifyContent="spaceAround">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText color="subdued">
|
||||
<FormattedMessage id="xpack.ml.fieldDataCard.loadingLabel" defaultMessage="Loading" />
|
||||
<FormattedMessage
|
||||
id="xpack.dataVisualizer.dataGrid.field.loadingLabel"
|
||||
defaultMessage="Loading"
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
|
@ -32,7 +32,7 @@ const NoFilterItems = () => {
|
|||
<EuiSpacer size="xs" />
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.multiSelectPicker.NoFiltersFoundMessage"
|
||||
id="xpack.dataVisualizer.multiSelectPicker.NoFiltersFoundMessage"
|
||||
defaultMessage="No filters found"
|
||||
/>
|
||||
</p>
|
|
@ -5,4 +5,4 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export { FileDataVisualizer } from '../../application';
|
||||
export { NotInDocsContent } from './not_in_docs_context';
|
|
@ -20,7 +20,7 @@ export const NotInDocsContent: FC = () => (
|
|||
<EuiSpacer size="s" />
|
||||
<EuiText textAlign="center">
|
||||
<FormattedMessage
|
||||
id="xpack.ml.fieldDataCard.fieldNotInDocsLabel"
|
||||
id="xpack.dataVisualizer.dataGrid.field.fieldNotInDocsLabel"
|
||||
defaultMessage="This field does not appear in any documents for the selected time range"
|
||||
/>
|
||||
</EuiText>
|
|
@ -12,11 +12,11 @@ import { EuiFlexGroup, EuiFlexItem, EuiCard, EuiIcon } from '@elastic/eui';
|
|||
import {
|
||||
DISCOVER_APP_URL_GENERATOR,
|
||||
DiscoverUrlGeneratorState,
|
||||
} from '../../../../../../../src/plugins/discover/public';
|
||||
import { TimeRange, RefreshInterval } from '../../../../../../../src/plugins/data/public';
|
||||
import { FindFileStructureResponse } from '../../../../../file_upload/common';
|
||||
import type { FileUploadPluginStart } from '../../../../../file_upload/public';
|
||||
import { useFileDataVisualizerKibana } from '../../kibana_context';
|
||||
} from '../../../../../../../../src/plugins/discover/public';
|
||||
import { TimeRange, RefreshInterval } from '../../../../../../../../src/plugins/data/public';
|
||||
import { FindFileStructureResponse } from '../../../../../../file_upload/common';
|
||||
import type { FileUploadPluginStart } from '../../../../../../file_upload/public';
|
||||
import { useDataVisualizerKibana } from '../../../kibana_context';
|
||||
|
||||
interface Props {
|
||||
fieldStats: FindFileStructureResponse['field_stats'];
|
||||
|
@ -44,7 +44,7 @@ export const ResultsLinks: FC<Props> = ({
|
|||
}) => {
|
||||
const {
|
||||
services: { fileUpload },
|
||||
} = useFileDataVisualizerKibana();
|
||||
} = useDataVisualizerKibana();
|
||||
|
||||
const [duration, setDuration] = useState({
|
||||
from: 'now-30m',
|
||||
|
@ -63,7 +63,7 @@ export const ResultsLinks: FC<Props> = ({
|
|||
urlGenerators: { getUrlGenerator },
|
||||
},
|
||||
},
|
||||
} = useFileDataVisualizerKibana();
|
||||
} = useDataVisualizerKibana();
|
||||
|
||||
useEffect(() => {
|
||||
let unmounted = false;
|
||||
|
@ -176,7 +176,7 @@ export const ResultsLinks: FC<Props> = ({
|
|||
icon={<EuiIcon size="xxl" type={`discoverApp`} />}
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.resultsLinks.viewIndexInDiscoverTitle"
|
||||
id="xpack.dataVisualizer.file.resultsLinks.viewIndexInDiscoverTitle"
|
||||
defaultMessage="View index in Discover"
|
||||
/>
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ export const ResultsLinks: FC<Props> = ({
|
|||
icon={<EuiIcon size="xxl" type={`managementApp`} />}
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.resultsLinks.indexManagementTitle"
|
||||
id="xpack.dataVisualizer.file.resultsLinks.indexManagementTitle"
|
||||
defaultMessage="Index Management"
|
||||
/>
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ export const ResultsLinks: FC<Props> = ({
|
|||
icon={<EuiIcon size="xxl" type={`managementApp`} />}
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.resultsLinks.indexPatternManagementTitle"
|
||||
id="xpack.dataVisualizer.file.resultsLinks.indexPatternManagementTitle"
|
||||
defaultMessage="Index Pattern Management"
|
||||
/>
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ export const ResultsLinks: FC<Props> = ({
|
|||
data-test-subj="fileDataVisFilebeatConfigLink"
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.resultsLinks.fileBeatConfig"
|
||||
id="xpack.dataVisualizer.file.resultsLinks.fileBeatConfig"
|
||||
defaultMessage="Create Filebeat configuration"
|
||||
/>
|
||||
}
|
|
@ -31,13 +31,13 @@ export const MetricFieldsCount: FC<MetricFieldsCountProps> = ({ metricsStats })
|
|||
gutterSize="s"
|
||||
alignItems="center"
|
||||
className="dataVisualizerFieldCountContainer"
|
||||
data-test-subj="mlDataVisualizerMetricFieldsSummary"
|
||||
data-test-subj="dataVisualizerMetricFieldsSummary"
|
||||
>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.searchPanel.numberFieldsLabel"
|
||||
id="xpack.dataVisualizer.searchPanel.numberFieldsLabel"
|
||||
defaultMessage="Number fields"
|
||||
/>
|
||||
</h5>
|
||||
|
@ -47,15 +47,15 @@ export const MetricFieldsCount: FC<MetricFieldsCountProps> = ({ metricsStats })
|
|||
<EuiNotificationBadge
|
||||
color="subdued"
|
||||
size="m"
|
||||
data-test-subj="mlDataVisualizerVisibleMetricFieldsCount"
|
||||
data-test-subj="dataVisualizerVisibleMetricFieldsCount"
|
||||
>
|
||||
<strong>{metricsStats.visibleMetricsCount}</strong>
|
||||
</EuiNotificationBadge>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText color="subdued" size="s" data-test-subj="mlDataVisualizerMetricFieldsCount">
|
||||
<EuiText color="subdued" size="s" data-test-subj="dataVisualizerMetricFieldsCount">
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.searchPanel.ofFieldsTotal"
|
||||
id="xpack.dataVisualizer.searchPanel.ofFieldsTotal"
|
||||
defaultMessage="of {totalCount} total"
|
||||
values={{ totalCount: metricsStats.totalMetricFieldsCount }}
|
||||
/>
|
|
@ -31,13 +31,13 @@ export const TotalFieldsCount: FC<TotalFieldsCountProps> = ({ fieldsCountStats }
|
|||
gutterSize="s"
|
||||
alignItems="center"
|
||||
className="dataVisualizerFieldCountContainer"
|
||||
data-test-subj="mlDataVisualizerFieldsSummary"
|
||||
data-test-subj="dataVisualizerFieldsSummary"
|
||||
>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.searchPanel.allFieldsLabel"
|
||||
id="xpack.dataVisualizer.searchPanel.allFieldsLabel"
|
||||
defaultMessage="All fields"
|
||||
/>
|
||||
</h5>
|
||||
|
@ -48,15 +48,15 @@ export const TotalFieldsCount: FC<TotalFieldsCountProps> = ({ fieldsCountStats }
|
|||
<EuiNotificationBadge
|
||||
color="subdued"
|
||||
size="m"
|
||||
data-test-subj="mlDataVisualizerVisibleFieldsCount"
|
||||
data-test-subj="dataVisualizerVisibleFieldsCount"
|
||||
>
|
||||
<strong>{fieldsCountStats.visibleFieldsCount}</strong>
|
||||
</EuiNotificationBadge>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText color="subdued" size="s" data-test-subj="mlDataVisualizerTotalFieldsCount">
|
||||
<EuiText color="subdued" size="s" data-test-subj="dataVisualizerTotalFieldsCount">
|
||||
<FormattedMessage
|
||||
id="xpack.fileDataVisualizer.searchPanel.ofFieldsTotal"
|
||||
id="xpack.dataVisualizer.searchPanel.ofFieldsTotal"
|
||||
defaultMessage="of {totalCount} total"
|
||||
values={{ totalCount: fieldsCountStats.totalFieldsCount }}
|
||||
/>
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue