From c170e588426851c649d9c46913db38557e32ae53 Mon Sep 17 00:00:00 2001 From: Eric Wei Date: Mon, 13 Nov 2023 10:19:58 -0800 Subject: [PATCH] Revert commits back to after 2.11 release (#1231) * Revert "Update empty allowed roles to admin only (#1217) (#1220)" This reverts commit 4288504cab7c7263664b96231fbcc7ed7273013d. Signed-off-by: Eric * Revert "Increment version to 2.11.1.0 (#1190)" This reverts commit ccd5fb8daa33989d17ac1f650d252f46f6d514c9. Signed-off-by: Eric * Revert "Add S3 integration for Nginx and VPC (#1214) (#1216)" This reverts commit e0a509ccc170daefff64cf9ee54670f560b1caa3. Signed-off-by: Eric * Revert "disabling inspect and default pattern/timestamp buttons when using async data sources (#1205) (#1212)" This reverts commit ca5ad02276a62800822922c8d9658ec487bb3087. Signed-off-by: Eric * Revert "Saved object datasource backward compatibility fixes (#1208) (#1210)" This reverts commit 467a0b33e7dc807ba2ece67bca0712b89e1a8eb0. Signed-off-by: Eric * Revert "Link integrations from datasources UI (#1203) (#1207)" This reverts commit 8e9fe5edb011f903d41a76f578f1d81b03089b7c. Signed-off-by: Eric * Revert "[Explorer] Fixes for cancel button and saved object loading (#1197) (#1201)" This reverts commit f0e7a9d3fb72a4edf7c6dba61be2687794c65ae9. Signed-off-by: Eric * Revert "Correct query schema for ELB mview generation (#1196) (#1199)" This reverts commit 0b7be956e56b317e17d70df6d1235d7a9ea1cafa. Signed-off-by: Eric * Revert "[Backport 2.11] Add integrations queries for Flint (#1195)" This reverts commit 97f46ba65757293386b9d84a14fa8dd359d2758b. Signed-off-by: Eric * Revert "remove husky pre-commit checks (#1192) (#1193)" This reverts commit 25d52f38177020c048b2876d60d4b82e05bb0e17. Signed-off-by: Eric * Revert "Bug fixes for observability count distribution and application analytics (#1187) (#1189)" This reverts commit e2440d240609942785dd2b62f2222d42fdd7bb5f. Signed-off-by: Eric * Revert "Support cancellation of async queries (#1177) (#1186)" This reverts commit 6b495f358d8d4b4fbfbaf9bf60058418d3caedff. Signed-off-by: Eric * Revert "[Explorer] Supports session for s3 direct query (#1178) (#1183)" This reverts commit d50047fa6a4872339a4a017dd3e404cbafc49f7a. Signed-off-by: Eric * Revert "[Explorer] Modify text in empty prompt (#1172) (#1182)" This reverts commit 95a60cc0eb3cea28d197f1c0bb71b13cf258e7ff. Signed-off-by: Eric * Revert "[Feature] Match discover look and feel (#1135) (#1179)" This reverts commit b69801e149df77efd2ae2b2305a4f4f350786064. Signed-off-by: Eric * Revert "config panel dark mode fix (#1169) (#1176)" This reverts commit 34696b31e1ad861aad76357727c7418040087aaf. Signed-off-by: Eric * Revert "Fix events home table and toast life time (#1170)" This reverts commit a9b36fc7eadddc484c856a6bb66803bbc9cea40b. Signed-off-by: Eric * Revert "Quiet react-dnd draggableId/droppableId warnings. (#1147) (#1166)" This reverts commit a2f9a006b483796070a3e922879b5945172d0109. Signed-off-by: Eric * Revert "Fix integration labeling to identify S3 integrations (#1157) (#1164)" This reverts commit 9de9aea11496408178f6a6c0a4ea8e5320262cdb. Signed-off-by: Eric * Revert "Remove loading progress for integration setup (#1156) (#1162)" This reverts commit a08721b2c2169a284575184eb959ae9ae401d8cb. Signed-off-by: Eric * Revert "Switch from toast to callout for integration set up failures (#1155) (#1159)" This reverts commit e6a474afe78dc6153c135c1d6e075f3ee537da31. Signed-off-by: Eric * Revert "Disable integration set up button if invalid (#1152) (#1161)" This reverts commit 74aae173aaaa2ed9cdd80592206289b80ba3ecd2. Signed-off-by: Eric * Revert "Update URL of create datasources, fix spacing (#1149) (#1154)" This reverts commit 0b66d83677f1a0611a4c1a23491583bad885ce99. Signed-off-by: Eric * Revert "Allow patch on allowedRoles (#1143) (#1145)" This reverts commit 0acc0f3681138779fd56bd4d3bb4606fb2349888. Signed-off-by: Eric * Revert "fix for explorer data grid not paginating (#1139) (#1141)" This reverts commit c5ead50dd6e69beef90db951ecd9868f29650ded. Signed-off-by: Eric --------- Signed-off-by: Eric --- .husky/.gitignore | 1 + .husky/pre-commit | 4 + common/constants/data_connections.ts | 8 - common/constants/data_sources.ts | 22 - common/constants/shared.ts | 7 - common/types/explorer.ts | 30 +- .../observability_saved_object_attributes.ts | 16 +- common/utils/index.ts | 1 - common/utils/query_session_utils.ts | 16 - common/utils/shared.ts | 8 - opensearch_dashboards.json | 6 +- package.json | 20 +- .../components/application.tsx | 2 - .../components/application_analytics/home.tsx | 2 - .../common/field_icon/field_icon.tsx | 2 +- public/components/common/query_utils/index.ts | 56 +- public/components/common/search/search.tsx | 79 +- .../components/common/search/sql_search.tsx | 150 +- .../data_connection.test.tsx.snap | 83 - .../components/manage/access_control_tab.tsx | 75 +- .../components/manage/data_connection.tsx | 8 - .../manage/manage_data_connections_table.tsx | 12 - .../components/new/configure_datasource.tsx | 10 +- .../new/configure_prometheus_datasource.tsx | 6 +- .../new/configure_s3_datasource.tsx | 6 +- .../new/new_datasource_card_view.tsx | 7 +- .../components/new/query_permissions.tsx | 10 +- public/components/datasources/home.tsx | 2 +- .../__snapshots__/no_results.test.tsx.snap | 296 +- .../__snapshots__/data_grid.test.tsx.snap | 378 +- .../datasources/datasources_selection.tsx | 239 +- .../explorer/direct_query_running.tsx | 58 +- .../explorer/events_views/data_grid.scss | 3 + .../explorer/events_views/data_grid.tsx | 114 +- .../explorer/events_views/docView.scss | 4 +- .../explorer/events_views/doc_flyout.tsx | 2 +- .../event_analytics/explorer/explorer.scss | 2 +- .../event_analytics/explorer/explorer.tsx | 428 +- .../event_analytics/explorer/log_explorer.tsx | 1 - .../event_analytics/explorer/no_results.tsx | 76 +- .../__snapshots__/field.test.tsx.snap | 634 +- .../__snapshots__/sidebar.test.tsx.snap | 18586 +++++++++------- .../explorer/sidebar/__tests__/field.test.tsx | 37 +- .../sidebar/__tests__/sidebar.test.tsx | 8 +- .../explorer/sidebar/field.tsx | 148 +- .../explorer/sidebar/field_insights.tsx | 10 +- .../sidebar/observability_sidebar.tsx | 95 - .../explorer/sidebar/sidebar.scss | 28 - .../explorer/sidebar/sidebar.tsx | 333 +- .../config_panel/config_panel.scss | 15 - .../data_config_panel_fields.tsx | 117 +- .../data_configurations_panel.scss | 46 - .../data_configurations_panel.tsx | 103 +- .../visualizations/direct_query_vis.tsx | 81 +- .../explorer/visualizations/index.tsx | 11 +- .../saved_query_table.test.tsx.snap | 8 +- .../components/event_analytics/home/home.tsx | 23 +- .../home/saved_objects_table.tsx | 2 +- public/components/event_analytics/index.tsx | 12 +- .../redux/slices/count_distribution_slice.ts | 1 - .../redux/slices/query_slice.ts | 2 +- .../redux/slices/search_meta_data_slice.ts | 61 +- .../utils/__tests__/utils.test.tsx | 16 +- .../event_analytics/utils/utils.tsx | 8 +- public/components/hooks/index.ts | 2 +- .../hooks/use_direct_query_search.ts | 4 + public/components/hooks/use_polling.ts | 78 +- .../setup_integration.test.tsx.snap | 171 +- .../__tests__/setup_integration.test.tsx | 1 - .../available_integration_overview_page.tsx | 18 +- .../components/create_integration_helpers.ts | 26 +- .../components/setup_integration.tsx | 233 +- public/components/metrics/index.scss | 2 +- .../visualizations/visualization.tsx | 2 +- .../datasources/obs_opensearch_datasource.ts | 30 - public/services/requests/sql.ts | 19 +- .../saved_object_client/client_factory.ts | 8 +- .../osd_saved_object_client.ts | 4 - .../osd_saved_objects/saved_searches.ts | 179 - .../osd_saved_objects/saved_visualization.ts | 6 - .../saved_objects_actions.ts | 31 +- .../explorer_saved_object_loader.ts | 442 - .../saved_object_loaders/ppl/ppl_loader.ts | 22 +- .../repository/apache/apache-1.0.0.json | 2 +- .../aws_cloudfront/aws_cloudfront-1.0.0.json | 2 +- .../aws_cloudtrail/aws_cloudtrail-1.0.0.json | 2 +- .../aws_elb/assets/create_mv-1.0.0.sql | 41 - .../aws_elb/assets/create_table-1.0.0.sql | 36 - .../aws_elb/assets/refresh_mv-1.0.0.sql | 1 - .../repository/aws_elb/aws_elb-1.0.0.json | 21 +- .../repository/aws_rds/aws_rds-1.0.0.json | 2 +- .../repository/aws_s3/aws_s3-1.0.0.json | 2 +- .../assets/create_mv_vpc-1.0.0.sql | 24 - .../assets/create_table_vpc-1.0.0.sql | 20 - .../assets/refresh_mv_vpc-1.0.0.sql | 1 - .../aws_vpc_flow/aws_vpc_flow-1.0.0.json | 21 +- .../repository/aws_waf/aws_waf-1.0.0.json | 2 +- .../__data__/repository/k8s/k8s-1.0.0.json | 2 +- .../nginx/assets/create_mv-1.0.0.sql | 10 - .../nginx/assets/create_table-1.0.0.sql | 18 - .../nginx/assets/refresh_mv-1.0.0.sql | 1 - .../repository/nginx/nginx-1.0.0.json | 21 +- .../repository/fs_data_adaptor.ts | 15 +- server/adaptors/integrations/validators.ts | 1 - .../opensearch_observability_plugin.ts | 16 - server/adaptors/ppl_plugin.ts | 2 +- server/plugin.ts | 6 +- .../data_connections_router.ts | 10 +- .../routes/datasources/datasources_router.ts | 30 - .../observability_saved_object.ts | 40 +- 110 files changed, 12378 insertions(+), 11884 deletions(-) create mode 100644 .husky/.gitignore create mode 100755 .husky/pre-commit delete mode 100644 common/constants/data_sources.ts delete mode 100644 common/utils/query_session_utils.ts delete mode 100644 common/utils/shared.ts delete mode 100644 public/components/event_analytics/explorer/sidebar/observability_sidebar.tsx create mode 100644 public/components/hooks/use_direct_query_search.ts delete mode 100644 public/framework/datasources/obs_opensearch_datasource.ts delete mode 100644 public/services/saved_objects/saved_object_client/osd_saved_objects/saved_searches.ts delete mode 100644 public/services/saved_objects/saved_object_loaders/explorer_saved_object_loader.ts delete mode 100644 server/adaptors/integrations/__data__/repository/aws_elb/assets/create_mv-1.0.0.sql delete mode 100644 server/adaptors/integrations/__data__/repository/aws_elb/assets/create_table-1.0.0.sql delete mode 100644 server/adaptors/integrations/__data__/repository/aws_elb/assets/refresh_mv-1.0.0.sql delete mode 100644 server/adaptors/integrations/__data__/repository/aws_vpc_flow/assets/create_mv_vpc-1.0.0.sql delete mode 100644 server/adaptors/integrations/__data__/repository/aws_vpc_flow/assets/create_table_vpc-1.0.0.sql delete mode 100644 server/adaptors/integrations/__data__/repository/aws_vpc_flow/assets/refresh_mv_vpc-1.0.0.sql delete mode 100644 server/adaptors/integrations/__data__/repository/nginx/assets/create_mv-1.0.0.sql delete mode 100644 server/adaptors/integrations/__data__/repository/nginx/assets/create_table-1.0.0.sql delete mode 100644 server/adaptors/integrations/__data__/repository/nginx/assets/refresh_mv-1.0.0.sql diff --git a/.husky/.gitignore b/.husky/.gitignore new file mode 100644 index 000000000..31354ec13 --- /dev/null +++ b/.husky/.gitignore @@ -0,0 +1 @@ +_ diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 000000000..d2ae35e84 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +yarn lint-staged diff --git a/common/constants/data_connections.ts b/common/constants/data_connections.ts index 23fd9a869..a0862e646 100644 --- a/common/constants/data_connections.ts +++ b/common/constants/data_connections.ts @@ -21,12 +21,4 @@ export const DatasourceTypeToDisplayName: { [key in DatasourceType]: string } = S3GLUE: 'Amazon S3', }; -export const PrometheusURL = 'Prometheus'; -export const AmazonS3URL = 'AmazonS3AWSGlue'; - -export const UrlToDatasourceType: { [key: string]: DatasourceType } = { - [PrometheusURL]: 'PROMETHEUS', - [AmazonS3URL]: 'S3GLUE', -}; - export type AuthMethod = 'noauth' | 'basicauth' | 'awssigv4'; diff --git a/common/constants/data_sources.ts b/common/constants/data_sources.ts deleted file mode 100644 index 931f1f729..000000000 --- a/common/constants/data_sources.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -export const DATA_SOURCE_NAME_URL_PARAM_KEY = 'datasourceName'; -export const DATA_SOURCE_TYPE_URL_PARAM_KEY = 'datasourceType'; -export const DEFAULT_DATA_SOURCE_TYPE = 'DEFAULT_INDEX_PATTERNS'; -export const DEFAULT_DATA_SOURCE_NAME = 'Default cluster'; -export const DEFAULT_DATA_SOURCE_OBSERVABILITY_DISPLAY_NAME = 'OpenSearch'; -export const DEFAULT_DATA_SOURCE_TYPE_NAME = 'Default Group'; -export const enum QUERY_LANGUAGE { - PPL = 'PPL', - SQL = 'SQL', - DQL = 'DQL', -} -export enum DATA_SOURCE_TYPES { - DEFAULT_CLUSTER_TYPE = DEFAULT_DATA_SOURCE_TYPE, - SPARK = 'spark', - S3Glue = 's3glue', -} -export const ASYNC_POLLING_INTERVAL = 2000; diff --git a/common/constants/shared.ts b/common/constants/shared.ts index 211645485..cc7a5147b 100644 --- a/common/constants/shared.ts +++ b/common/constants/shared.ts @@ -15,8 +15,6 @@ export const OBSERVABILITY_BASE = '/api/observability'; export const INTEGRATIONS_BASE = '/api/integrations'; export const JOBS_BASE = '/query/jobs'; export const DATACONNECTIONS_BASE = '/api/dataconnections'; -export const EDIT = '/edit'; -export const SECURITY_ROLES = '/api/v1/configuration/roles'; export const EVENT_ANALYTICS = '/event_analytics'; export const SAVED_OBJECTS = '/saved_objects'; export const SAVED_QUERY = '/query'; @@ -242,11 +240,6 @@ export const WAITING_TIME_ON_USER_ACTIONS = 300; export const VISUALIZATION_ERROR = { NO_DATA: 'No data found.', INVALID_DATA: 'Invalid visualization data', - NO_SERIES: 'Add a field to start', }; export const S3_DATASOURCE_TYPE = 'S3_DATASOURCE'; - -export const ASYNC_QUERY_SESSION_ID = 'async-query-session-id'; - -export const DIRECT_DUMMY_QUERY = 'select 1'; diff --git a/common/types/explorer.ts b/common/types/explorer.ts index 9daf69074..af94da802 100644 --- a/common/types/explorer.ts +++ b/common/types/explorer.ts @@ -38,7 +38,6 @@ import { SavedObjectsStart, } from '../../../../src/core/public/saved_objects'; import { ChromeBreadcrumb } from '../../../../src/core/public/chrome'; -import { DataSourceType } from '../../../../src/plugins/data/public'; export interface IQueryTab { id: string; @@ -146,23 +145,13 @@ export interface IExplorerProps { queryManager?: QueryManager; } -export interface SelectedDataSource { - label: string; - name: string; - value: string; - type: string; - ds?: DataSourceType; -} - -export interface SavedQuery extends SavedObjectAttributes { +export interface SavedQuery { description: string; name: string; query: string; selected_date_range: { start: string; end: string; text: string }; selected_fields: { text: string; tokens: IField[] }; selected_timestamp: IField; - dataSources: string; // list of type SelectedDataSources that is stringified - queryLang: string; } export interface SavedVisualization extends SavedObjectAttributes { @@ -177,8 +166,6 @@ export interface SavedVisualization extends SavedObjectAttributes { user_configs?: string; units_of_measure?: string; application_id?: string; - dataSources: string; // list of type SelectedDataSources that is stringified - queryLang: string; } export interface ExplorerDataType { @@ -419,18 +406,3 @@ export interface GridSortingColumn { id: string; direction: 'asc' | 'desc'; } - -export enum DirectQueryLoadingStatus { - SUCCESS = 'SUCCESS', - FAILED = 'FAILED', - RUNNING = 'RUNNING', - SCHEDULED = 'SCHEDULED', - CANCELED = 'CANCELED', -} - -export interface DirectQueryRequest { - query: string; - lang: string; - datasource: string; - sessionId?: string; -} diff --git a/common/types/observability_saved_object_attributes.ts b/common/types/observability_saved_object_attributes.ts index a98f0b4b2..520f922bc 100644 --- a/common/types/observability_saved_object_attributes.ts +++ b/common/types/observability_saved_object_attributes.ts @@ -4,14 +4,10 @@ */ import { SavedObjectAttributes } from '../../../../src/core/types'; -import { SavedQuery, SavedVisualization } from './explorer'; +import { SavedVisualization } from './explorer'; export const VISUALIZATION_SAVED_OBJECT = 'observability-visualization'; -export const SEARCH_SAVED_OBJECT = 'observability-search'; -export const OBSERVABILTY_SAVED_OBJECTS = [ - VISUALIZATION_SAVED_OBJECT, - SEARCH_SAVED_OBJECT, -] as const; +export const OBSERVABILTY_SAVED_OBJECTS = [VISUALIZATION_SAVED_OBJECT] as const; export const SAVED_OBJECT_VERSION = 1; export interface VisualizationSavedObjectAttributes extends SavedObjectAttributes { @@ -21,11 +17,3 @@ export interface VisualizationSavedObjectAttributes extends SavedObjectAttribute createdTimeMs: number; savedVisualization: SavedVisualization; } - -export interface SearchSavedObjectAttributes extends SavedObjectAttributes { - title: string; - description: string; - version: number; - createdTimeMs: number; - savedQuery: SavedQuery; -} diff --git a/common/utils/index.ts b/common/utils/index.ts index 0becefc0a..284c1f4b0 100644 --- a/common/utils/index.ts +++ b/common/utils/index.ts @@ -10,7 +10,6 @@ export { buildRawQuery, composeFinalQuery, removeBacktick, - getSavingCommonParams, } from '../../public/components/common/query_utils'; export * from './core_services'; diff --git a/common/utils/query_session_utils.ts b/common/utils/query_session_utils.ts deleted file mode 100644 index ad0e0a1af..000000000 --- a/common/utils/query_session_utils.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -import { ASYNC_QUERY_SESSION_ID } from '../constants/shared'; - -export const setAsyncSessionId = (value: string | null) => { - if (value !== null) { - sessionStorage.setItem(ASYNC_QUERY_SESSION_ID, value); - } -}; - -export const getAsyncSessionId = () => { - return sessionStorage.getItem(ASYNC_QUERY_SESSION_ID); -}; diff --git a/common/utils/shared.ts b/common/utils/shared.ts deleted file mode 100644 index a6f226a6d..000000000 --- a/common/utils/shared.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -export function get(obj: Record, path: string, defaultValue?: T): T { - return path.split('.').reduce((acc: any, part: string) => acc && acc[part], obj) || defaultValue; -} diff --git a/opensearch_dashboards.json b/opensearch_dashboards.json index 537037782..b45c522b5 100644 --- a/opensearch_dashboards.json +++ b/opensearch_dashboards.json @@ -1,7 +1,7 @@ { "id": "observabilityDashboards", - "version": "2.11.1.0", - "opensearchDashboardsVersion": "2.11.1", + "version": "2.11.0.0", + "opensearchDashboardsVersion": "2.11.0", "server": true, "ui": true, "requiredPlugins": [ @@ -21,4 +21,4 @@ "optionalPlugins": [ "managementOverview" ] -} \ No newline at end of file +} diff --git a/package.json b/package.json index b93523655..b07010b1d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "observability-dashboards", - "version": "2.11.1.0", + "version": "2.11.0.0", "main": "index.ts", "license": "Apache-2.0", "scripts": { @@ -10,8 +10,17 @@ "cypress:run": "TZ=America/Los_Angeles cypress run", "cypress:open": "TZ=America/Los_Angeles cypress open", "plugin-helpers": "node ../../scripts/plugin_helpers", + "prepare": "husky install", + "lint:es": "node ../../scripts/eslint", + "lint": "yarn lint:es", "cypress:parallel": "cypress-parallel -s cypress:run -t 2 -d .cypress/integration" }, + "lint-staged": { + "*.{ts,tsx,js,jsx}": [ + "yarn lint --fix", + "git add" + ] + }, "dependencies": { "@algolia/autocomplete-core": "^1.4.1", "@algolia/autocomplete-theme-classic": "^1.2.1", @@ -67,5 +76,10 @@ "tough-cookie": "^4.1.3", "semver": "^7.5.2", "@cypress/request": "^3.0.0" - } -} \ No newline at end of file + }, + "eslintIgnore": [ + "common/query_manager/antlr/output/*", + "node_modules/*", + "target/*" + ] +} diff --git a/public/components/application_analytics/components/application.tsx b/public/components/application_analytics/components/application.tsx index bdfea879a..d5ba1b8fe 100644 --- a/public/components/application_analytics/components/application.tsx +++ b/public/components/application_analytics/components/application.tsx @@ -116,7 +116,6 @@ export function Application(props: AppDetailProps) { callback, queryManager, mode, - dataSourcePluggables, } = props; const [application, setApplication] = useState({ id: '', @@ -372,7 +371,6 @@ export function Application(props: AppDetailProps) { callbackInApp={callbackInApp} queryManager={queryManager} curSelectedTabId={selectedTabId} - dataSourcePluggables={dataSourcePluggables} /> ); }; diff --git a/public/components/application_analytics/home.tsx b/public/components/application_analytics/home.tsx index c360e50d9..a97f56f34 100644 --- a/public/components/application_analytics/home.tsx +++ b/public/components/application_analytics/home.tsx @@ -73,7 +73,6 @@ export const Home = (props: HomeProps) => { chrome, notifications, queryManager, - dataSourcePluggables, } = props; const [triggerSwitchToEvent, setTriggerSwitchToEvent] = useState(0); const dispatch = useDispatch(); @@ -141,7 +140,6 @@ export const Home = (props: HomeProps) => { setEndTime, mode: 'data_prepper', dataPrepperIndicesExist: indicesExist, - dataSourcePluggables, }; const setToast = (title: string, color = 'success', text?: ReactChild) => { diff --git a/public/components/common/field_icon/field_icon.tsx b/public/components/common/field_icon/field_icon.tsx index e5b2d0117..467c2c7c0 100644 --- a/public/components/common/field_icon/field_icon.tsx +++ b/public/components/common/field_icon/field_icon.tsx @@ -50,7 +50,7 @@ export const typeToEuiIconMap: Partial> = { export function FieldIcon({ type, label, - size = 's', + size = 'l', scripted, className, ...rest diff --git a/public/components/common/query_utils/index.ts b/public/components/common/query_utils/index.ts index 9f4024bb3..98d0b54ff 100644 --- a/public/components/common/query_utils/index.ts +++ b/public/components/common/query_utils/index.ts @@ -6,12 +6,10 @@ import dateMath from '@elastic/datemath'; import { Moment } from 'moment-timezone'; import { isEmpty } from 'lodash'; -import { SearchMetaData } from 'public/components/event_analytics/redux/slices/search_meta_data_slice'; +import moment from 'moment'; import { + DATE_PICKER_FORMAT, PPL_DEFAULT_PATTERN_REGEX_FILETER, - SELECTED_DATE_RANGE, - SELECTED_FIELDS, - SELECTED_TIMESTAMP, } from '../../../../common/constants/explorer'; import { PPL_DATE_FORMAT, @@ -19,7 +17,6 @@ import { PPL_INDEX_REGEX, PPL_NEWLINE_REGEX, } from '../../../../common/constants/shared'; -import { IExplorerFields, IQuery } from '../../../../common/types/explorer'; /* * "Query Utils" This file contains different reused functions in operational panels @@ -189,6 +186,9 @@ export const preprocessQuery = ({ if (!start || !end) return finalQuery; + const formattedStart = moment(start).utc().format(DATE_PICKER_FORMAT); + const formattedEnd = moment(end).utc().format(DATE_PICKER_FORMAT); + const promQLTokens = parsePromQLIntoKeywords(rawQuery); if (promQLTokens?.connection) { @@ -246,14 +246,23 @@ export const buildPatternsQuery = ( }; export const buildQuery = (baseQuery: string, currQuery: string) => { - if (!currQuery) return baseQuery; - return `${baseQuery} | ${currQuery}`; + let fullQuery: string; + if (baseQuery) { + fullQuery = baseQuery; + if (currQuery) { + fullQuery += '| ' + currQuery; + } + } else { + fullQuery = currQuery; + } + return fullQuery; }; -export const buildRawQuery = (query: IQuery, appBaseQuery: string) => { - if (appBaseQuery && !query.rawQuery.includes(appBaseQuery)) - return buildQuery(appBaseQuery, query.rawQuery); - return query.rawQuery; +export const buildRawQuery = (query: any, appBaseQuery: string) => { + const rawQueryStr = (query.rawQuery as string).includes(appBaseQuery) + ? query.rawQuery + : buildQuery(appBaseQuery, query.rawQuery); + return rawQueryStr; }; export const composeFinalQuery = ( @@ -285,28 +294,3 @@ export const removeBacktick = (stringContainsBacktick: string) => { if (!stringContainsBacktick) return ''; return stringContainsBacktick.replace(/`/g, ''); }; - -export const getSavingCommonParams = ( - queryState: IQuery, - appBaseQuery: string, - fields: IExplorerFields, - savingTitle: string, - explorerSearchMeta: SearchMetaData -) => { - return { - dataSources: JSON.stringify([ - { - name: explorerSearchMeta.datasources?.[0]?.name || '', - type: explorerSearchMeta.datasources?.[0]?.type || '', - label: explorerSearchMeta.datasources?.[0]?.label || '', - value: explorerSearchMeta.datasources?.[0]?.value || '', - }, - ]), - queryLang: explorerSearchMeta.lang, - query: buildRawQuery(queryState, appBaseQuery), - fields: fields[SELECTED_FIELDS], - dateRange: queryState[SELECTED_DATE_RANGE], - name: savingTitle, - timestamp: queryState[SELECTED_TIMESTAMP], - }; -}; diff --git a/public/components/common/search/search.tsx b/public/components/common/search/search.tsx index de450d09c..604575850 100644 --- a/public/components/common/search/search.tsx +++ b/public/components/common/search/search.tsx @@ -20,21 +20,24 @@ import { } from '@elastic/eui'; import { isEqual } from 'lodash'; import React, { useEffect, useState } from 'react'; -import { useDispatch } from 'react-redux'; -import { APP_ANALYTICS_TAB_ID_REGEX } from '../../../../common/constants/explorer'; +import { useDispatch, useSelector } from 'react-redux'; +import { APP_ANALYTICS_TAB_ID_REGEX, RAW_QUERY } from '../../../../common/constants/explorer'; import { PPL_SPAN_REGEX } from '../../../../common/constants/shared'; import { uiSettingsService } from '../../../../common/utils'; import { useFetchEvents } from '../../../components/event_analytics/hooks'; +import { changeQuery } from '../../../components/event_analytics/redux/slices/query_slice'; import { usePolling } from '../../../components/hooks/use_polling'; import { coreRefs } from '../../../framework/core_refs'; import { SQLService } from '../../../services/requests/sql'; import { SavePanel } from '../../event_analytics/explorer/save_panel'; -import { update as updateSearchMetaData } from '../../event_analytics/redux/slices/search_meta_data_slice'; +import { + selectSearchMetaData, + update as updateSearchMetaData, +} from '../../event_analytics/redux/slices/search_meta_data_slice'; import { PPLReferenceFlyout } from '../helpers'; import { LiveTailButton, StopLiveButton } from '../live_tail/live_tail_button'; import { Autocomplete } from './autocomplete'; import { DatePicker } from './date_picker'; -import { QUERY_LANGUAGE } from '../../../../common/constants/data_sources'; export interface IQueryBarProps { query: string; tempQuery: string; @@ -94,12 +97,14 @@ export const Search = (props: any) => { setIsQueryRunning, } = props; + const explorerSearchMetadata = useSelector(selectSearchMetaData)[tabId]; const dispatch = useDispatch(); const appLogEvents = tabId.match(APP_ANALYTICS_TAB_ID_REGEX); const [isSavePanelOpen, setIsSavePanelOpen] = useState(false); const [isLanguagePopoverOpen, setLanguagePopoverOpen] = useState(false); const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); - const [queryLang, setQueryLang] = useState(QUERY_LANGUAGE.PPL); + const [queryLang, setQueryLang] = useState('PPL'); + const [jobId, setJobId] = useState(''); const sqlService = new SQLService(coreRefs.http); const { application } = coreRefs; @@ -114,7 +119,7 @@ export const Search = (props: any) => { }, 5000); const requestParams = { tabId }; - const { dispatchOnGettingHis } = useFetchEvents({ + const { getLiveTail, getEvents, getAvailableFields, dispatchOnGettingHis } = useFetchEvents({ pplService: new SQLService(coreRefs.http), requestParams, }); @@ -158,9 +163,10 @@ export const Search = (props: any) => { ); const handleQueryLanguageChange = (lang: string) => { - if (lang === QUERY_LANGUAGE.DQL) { - application!.navigateToUrl('../app/data-explorer/discover'); - return; + if (lang === 'DQL') { + return application!.navigateToUrl( + `../app/data-explorer/discover#?_a=(discover:(columns:!(_source),isDirty:!f,sort:!()),metadata:(indexPattern:'${explorerSearchMetadata.datasources[0].value}',view:discover))&_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:now-15m,to:now))&_q=(filters:!(),query:(language:kuery,query:''))` + ); } dispatch( updateSearchMetaData({ @@ -181,16 +187,10 @@ export const Search = (props: any) => { }; const languagePopOverItems = [ - handleQueryLanguageChange(QUERY_LANGUAGE.PPL)} - > + handleQueryLanguageChange('PPL')}> PPL , - handleQueryLanguageChange(QUERY_LANGUAGE.DQL)} - > + handleQueryLanguageChange('DQL')}> DQL , ]; @@ -215,9 +215,24 @@ export const Search = (props: any) => { } }, [pollingResult, pollingError]); + useEffect(() => { + if (explorerSearchMetadata.datasources?.[0]?.type === 'DEFAULT_INDEX_PATTERNS') { + const queryWithSelectedSource = `source = ${explorerSearchMetadata.datasources[0].label}`; + handleQueryChange(queryWithSelectedSource); + dispatch( + changeQuery({ + tabId, + query: { + [RAW_QUERY]: queryWithSelectedSource, + }, + }) + ); + } + }, [explorerSearchMetadata.datasources]); + return (
- + {appLogEvents && ( @@ -227,21 +242,19 @@ export const Search = (props: any) => { )} - {!appLogEvents && ( - - - - - - )} - + + + + + + { query, tempQuery, handleQueryChange, + handleTimePickerChange, dslService, + startTime, + endTime, + setStartTime, + setEndTime, + setIsOutputStale, selectedPanelName, selectedCustomPanelOptions, setSelectedPanelName, @@ -74,24 +75,33 @@ export const DirectSearch = (props: any) => { savedObjects, showSavePanelOptionsList, showSaveButton = true, + handleTimeRangePickerRefresh, + isLiveTailPopoverOpen, + closeLiveTailPopover, + popoverItems, + isLiveTailOn, selectedSubTabId, searchBarConfigs = {}, getSuggestions, onItemSelect, tabId = '', baseQuery = '', + stopLive, + setIsLiveTailPopoverOpen, + liveTailName, curVisId, setSubType, setIsQueryRunning, } = props; - const explorerSearchMetadata = useSelector(selectSearchMetaData)[tabId] || {}; + const explorerSearchMetadata = useSelector(selectSearchMetaData)[tabId]; const dispatch = useDispatch(); const appLogEvents = tabId.match(APP_ANALYTICS_TAB_ID_REGEX); const [isSavePanelOpen, setIsSavePanelOpen] = useState(false); const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); const [isLanguagePopoverOpen, setLanguagePopoverOpen] = useState(false); - const [queryLang, setQueryLang] = useState(explorerSearchMetadata.lang || QUERY_LANGUAGE.SQL); + const [queryLang, setQueryLang] = useState('SQL'); + const [jobId, setJobId] = useState(''); const sqlService = new SQLService(coreRefs.http); const { application } = coreRefs; @@ -103,10 +113,10 @@ export const DirectSearch = (props: any) => { stopPolling, } = usePolling((params) => { return sqlService.fetchWithJobId(params); - }, ASYNC_POLLING_INTERVAL); + }, 5000); const requestParams = { tabId }; - const { dispatchOnGettingHis } = useFetchEvents({ + const { getLiveTail, getEvents, getAvailableFields, dispatchOnGettingHis } = useFetchEvents({ pplService: new SQLService(coreRefs.http), requestParams, }); @@ -141,10 +151,16 @@ export const DirectSearch = (props: any) => { const handleQueryLanguageChange = (lang: string) => { if (lang === 'DQL') { - application!.navigateToUrl('../app/data-explorer/discover'); - return; + return application!.navigateToUrl( + `../app/data-explorer/discover#?_a=(discover:(columns:!(_source),isDirty:!f,sort:!()),metadata:(indexPattern:'${explorerSearchMetadata.datasources[0].value}',view:discover))&_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:now-15m,to:now))&_q=(filters:!(),query:(language:kuery,query:''))` + ); } - dispatch(updateSearchMetaData({ tabId, data: { lang } })); + dispatch( + updateSearchMetaData({ + tabId, + data: { lang }, + }) + ); setQueryLang(lang); closeLanguagePopover(); }; @@ -158,16 +174,10 @@ export const DirectSearch = (props: any) => { }; const languagePopOverItems = [ - handleQueryLanguageChange(QUERY_LANGUAGE.SQL)} - > + handleQueryLanguageChange('SQL')}> SQL , - handleQueryLanguageChange(QUERY_LANGUAGE.PPL)} - > + handleQueryLanguageChange('PPL')}> PPL , ]; @@ -184,31 +194,25 @@ export const DirectSearch = (props: any) => { ); - const onQuerySearch = (lang: string) => { + const onQuerySearch = (lang) => { setIsQueryRunning(true); - batch(() => { - dispatch( - changeQuery({ tabId, query: { [RAW_QUERY]: tempQuery.replaceAll(PPL_NEWLINE_REGEX, '') } }) - ); - dispatch(updateSearchMetaData({ tabId, data: { isPolling: true, lang } })); - }); - const sessionId = getAsyncSessionId(); - const requestPayload = { - lang: lang.toLowerCase(), - query: tempQuery || query, - datasource: explorerSearchMetadata.datasources[0].label, - } as DirectQueryRequest; - - if (sessionId) { - requestPayload.sessionId = sessionId; - } - + dispatch( + updateSearchMetaData({ + tabId, + data: { + isPolling: true, + }, + }) + ); sqlService - .fetch(requestPayload) + .fetch({ + lang: lowerCase(lang), + query: tempQuery || query, + datasource: explorerSearchMetadata.datasources[0].name, + }) .then((result) => { - setAsyncSessionId(getObjValue(result, 'sessionId', null)); if (result.queryId) { - dispatch(updateSearchMetaData({ tabId, data: { queryId: result.queryId } })); + setJobId(result.queryId); startPolling({ queryId: result.queryId, }); @@ -219,15 +223,13 @@ export const DirectSearch = (props: any) => { .catch((e) => { setIsQueryRunning(false); console.error(e); - }); + }) + .finally(() => {}); }; useEffect(() => { // cancel direct query - if (!pollingResult) return; - const { status, datarows } = pollingResult; - - if (status === DirectQueryLoadingStatus.SUCCESS || datarows) { + if (pollingResult && (pollingResult.status === 'SUCCESS' || pollingResult.datarows)) { // stop polling stopPolling(); setIsQueryRunning(false); @@ -236,30 +238,16 @@ export const DirectSearch = (props: any) => { tabId, data: { isPolling: false, - status: undefined, }, }) ); // update page with data dispatchOnGettingHis(pollingResult, ''); - return; } - dispatch( - updateSearchMetaData({ - tabId, - data: { status }, - }) - ); }, [pollingResult, pollingError]); useEffect(() => { - return () => { - stopPolling(); - }; - }, []); - - useEffect(() => { - if (!explorerSearchMetadata.isPolling) { + if (explorerSearchMetadata.isPolling === false) { stopPolling(); setIsQueryRunning(false); } @@ -267,7 +255,7 @@ export const DirectSearch = (props: any) => { return (
- + {appLogEvents && ( @@ -277,21 +265,19 @@ export const DirectSearch = (props: any) => { )} - {!appLogEvents && ( - - - - - - )} - + + + + + + { isSuggestionDisabled={queryLang === 'SQL'} isDisabled={explorerSearchMetadata.isPolling} /> - {queryLang === QUERY_LANGUAGE.PPL && ( + {queryLang === 'PPL' && (
-
- -

-
-
-
- -
-
- - - -
-

- Explore data faster through integrations -

-
-
-
-
@@ -827,25 +763,6 @@ exports[`Data Connection Page test Renders S3 data connection page with data 1`] Control which OpenSearch users have access to this data source. -
- -

{ - const [mode, setMode] = useState<'view' | 'edit'>('view'); - const [roles, setRoles] = useState([]); - const [hasSecurityAccess, setHasSecurityAccess] = useState(true); - const { http } = coreRefs; - - useEffect(() => { - http! - .get(SECURITY_ROLES) - .then((data) => - setRoles( - Object.keys(data.data).map((key) => { - return { label: key }; - }) - ) - ) - .catch((err) => setHasSecurityAccess(false)); - }, []); - const [selectedQueryPermissionRoles, setSelectedQueryPermissionRoles] = useState( props.allowedRoles.map((role) => { return { label: role }; @@ -73,30 +44,6 @@ export const AccessControlTab = (props: AccessControlTabProps) => { ); }; - const EditAccessControlDetails = () => { - return ( - - - - ); - }; - - const saveChanges = () => { - http!.post(`${DATACONNECTIONS_BASE}${EDIT}`, { - body: JSON.stringify({ - name: props.dataConnection, - allowedRoles: selectedQueryPermissionRoles.map((role) => role.label), - }), - }); - setMode('view'); - }; - const AccessControlHeader = () => { return ( @@ -106,14 +53,6 @@ export const AccessControlTab = (props: AccessControlTabProps) => { Control which OpenSearch users have access to this data source. - - setMode(mode === 'view' ? 'edit' : 'view')} - > - {mode === 'view' ? 'Edit' : 'Cancel'} - - ); }; @@ -126,17 +65,9 @@ export const AccessControlTab = (props: AccessControlTabProps) => { - {mode === 'view' ? : } + - {mode === 'edit' && ( - { - setMode('view'); - }} - onSave={saveChanges} - /> - )} ); diff --git a/public/components/datasources/components/manage/data_connection.tsx b/public/components/datasources/components/manage/data_connection.tsx index 4c9da43a3..12b40df10 100644 --- a/public/components/datasources/components/manage/data_connection.tsx +++ b/public/components/datasources/components/manage/data_connection.tsx @@ -98,14 +98,6 @@ export const DataConnection = (props: any) => { } /> - - } - title={'Integrate data'} - description="Explore data faster through integrations" - onClick={() => application!.navigateToApp(observabilityIntegrationsID)} - /> - ); }; diff --git a/public/components/datasources/components/manage/manage_data_connections_table.tsx b/public/components/datasources/components/manage/manage_data_connections_table.tsx index 4d8c65751..d2fe01326 100644 --- a/public/components/datasources/components/manage/manage_data_connections_table.tsx +++ b/public/components/datasources/components/manage/manage_data_connections_table.tsx @@ -22,7 +22,6 @@ import { HomeProps } from '../../home'; import { DataConnectionsDescription } from './manage_data_connections_description'; import { DATACONNECTIONS_BASE, - observabilityIntegrationsID, observabilityLogsID, observabilityMetricsID, } from '../../../../../common/constants/shared'; @@ -138,17 +137,6 @@ export const ManageDataConnectionsTable = (props: HomeProps) => { }, 'data-test-subj': 'action-accelerate', }, - { - name: 'Integrate data', - isPrimary: false, - icon: 'integrationGeneral', - type: 'icon', - available: (datasource: DataConnection) => datasource.connectionType !== 'PROMETHEUS', - onClick: () => { - application!.navigateToApp(observabilityIntegrationsID); - }, - 'data-test-subj': 'action-integrate', - }, { name: 'Delete', description: 'Delete this data source', diff --git a/public/components/datasources/components/new/configure_datasource.tsx b/public/components/datasources/components/new/configure_datasource.tsx index 9cd7ccd34..244ab0c4b 100644 --- a/public/components/datasources/components/new/configure_datasource.tsx +++ b/public/components/datasources/components/new/configure_datasource.tsx @@ -18,7 +18,7 @@ import { import React, { useCallback, useEffect, useState } from 'react'; import { ConfigureS3Datasource } from './configure_s3_datasource'; import { coreRefs } from '../../../../../public/framework/core_refs'; -import { DATACONNECTIONS_BASE, SECURITY_ROLES } from '../../../../../common/constants/shared'; +import { DATACONNECTIONS_BASE } from '../../../../../common/constants/shared'; import { ReviewS3Datasource } from './review_s3_datasource_configuration'; import { useToast } from '../../../../../public/components/common/toast'; import { DatasourceType, Role } from '../../../../../common/types/data_connections'; @@ -27,18 +27,17 @@ import { ReviewPrometheusDatasource } from './review_prometheus_datasource_confi import { AuthMethod, DatasourceTypeToDisplayName, - UrlToDatasourceType, } from '../../../../../common/constants/data_connections'; import { formatError } from '../../../../../public/components/event_analytics/utils'; import { NotificationsStart } from '../../../../../../../src/core/public'; interface ConfigureDatasourceProps { - urlType: string; + type: DatasourceType; notifications: NotificationsStart; } export function Configure(props: ConfigureDatasourceProps) { - const { urlType, notifications } = props; + const { type, notifications } = props; const { http, chrome } = coreRefs; const { setToast } = useToast(); const [error, setError] = useState(''); @@ -56,7 +55,6 @@ export function Configure(props: ConfigureDatasourceProps) { const [hasSecurityAccess, setHasSecurityAccess] = useState(true); const [selectedQueryPermissionRoles, setSelectedQueryPermissionRoles] = useState([]); const [page, setPage] = useState<'configure' | 'review'>('configure'); - const type = UrlToDatasourceType[urlType]; const ConfigureDatasourceSteps = [ { title: 'Configure data source', @@ -69,7 +67,7 @@ export function Configure(props: ConfigureDatasourceProps) { useEffect(() => { http! - .get(SECURITY_ROLES) + .get('/api/v1/configuration/roles') .then((data) => setRoles( Object.keys(data.data).map((key) => { diff --git a/public/components/datasources/components/new/configure_prometheus_datasource.tsx b/public/components/datasources/components/new/configure_prometheus_datasource.tsx index 853351cb8..6f4ecb4f0 100644 --- a/public/components/datasources/components/new/configure_prometheus_datasource.tsx +++ b/public/components/datasources/components/new/configure_prometheus_datasource.tsx @@ -106,7 +106,7 @@ export const ConfigurePrometheusDatasource = (props: ConfigurePrometheusDatasour

Data source details

- +

Prometheus data location

- + <> @@ -156,7 +156,7 @@ export const ConfigurePrometheusDatasource = (props: ConfigurePrometheusDatasour

Authentication details

- + {

Data source details

- + {

AWS Glue Data Catalog authentication details

- + <> @@ -169,7 +169,7 @@ export const ConfigureS3Datasource = (props: ConfigureS3DatasourceProps) => {

AWS Glue Data Catalog index store details

- + <> diff --git a/public/components/datasources/components/new/new_datasource_card_view.tsx b/public/components/datasources/components/new/new_datasource_card_view.tsx index 46845df10..bbd695bfb 100644 --- a/public/components/datasources/components/new/new_datasource_card_view.tsx +++ b/public/components/datasources/components/new/new_datasource_card_view.tsx @@ -9,7 +9,6 @@ import { NewDatasourceDescription } from './new_datasource_description'; import s3Svg from '../../icons/s3-logo.svg'; import prometheusSvg from '../../icons/prometheus-logo.svg'; import { DatasourceType } from '../../../../../common/types/data_connections'; -import { AmazonS3URL, PrometheusURL } from '../../../../../common/constants/data_connections'; export interface DatasourceCard { name: DatasourceType; @@ -23,17 +22,17 @@ export function NewDatasourceCardView() { const Datasources: DatasourceCard[] = [ { name: 'S3GLUE', - displayName: 'Amazon S3', + displayName: 'S3', description: 'Connect to Amazon S3 via AWS Glue Data Catalog', displayIcon: , - onClick: () => (window.location.hash = `#/configure/${AmazonS3URL}`), + onClick: () => (window.location.hash = `#/configure/S3GLUE`), }, { name: 'PROMETHEUS', displayName: 'Prometheus', description: 'Connect to Prometheus', displayIcon: , - onClick: () => (window.location.hash = `#/configure/${PrometheusURL}`), + onClick: () => (window.location.hash = `#/configure/PROMETHEUS`), }, ]; diff --git a/public/components/datasources/components/new/query_permissions.tsx b/public/components/datasources/components/new/query_permissions.tsx index 0c0853b57..d5a899c08 100644 --- a/public/components/datasources/components/new/query_permissions.tsx +++ b/public/components/datasources/components/new/query_permissions.tsx @@ -30,8 +30,7 @@ export const QueryPermissionsConfiguration = (props: PermissionsConfigurationPro }, { id: QUERY_ALL, - label: 'Admin only - only accessible by the admin', - disabled: !hasSecurityAccess, + label: 'Everyone - accessible by all users on this cluster', }, ]; @@ -83,12 +82,7 @@ export const QueryPermissionsConfiguration = (props: PermissionsConfigurationPro { - if (id === QUERY_ALL) { - setSelectedRoles([]); - } - setSelectedAccessLevel(id); - }} + onChange={(id) => setSelectedAccessLevel(id)} name="query-radio-group" legend={{ children: Query access level, diff --git a/public/components/datasources/home.tsx b/public/components/datasources/home.tsx index a6a45ca28..0bbfa93cd 100644 --- a/public/components/datasources/home.tsx +++ b/public/components/datasources/home.tsx @@ -59,7 +59,7 @@ export const Home = (props: HomeProps) => { exact path={['/configure/:id+']} render={(routerProps) => ( - + )} /> diff --git a/public/components/event_analytics/__tests__/__snapshots__/no_results.test.tsx.snap b/public/components/event_analytics/__tests__/__snapshots__/no_results.test.tsx.snap index 3e23d7126..50c496076 100644 --- a/public/components/event_analytics/__tests__/__snapshots__/no_results.test.tsx.snap +++ b/public/components/event_analytics/__tests__/__snapshots__/no_results.test.tsx.snap @@ -2,137 +2,211 @@ exports[`No result component Renders No result component 1`] = ` - -
+ - -
+ - + + +
-
- - } +
-
+ } >
- - - + + + + - + No results match your search criteria - - - + + +
-
-
-
- - -
- -
- - -
+ -

+ + +
- - - Select a data source, expand your time range, or modify the query - - -

-

- - - After selection, check the time range, query filters, fields, and query - - -

-
-
-
- -
- -
- + + Expand your time range or modify your query + + +

+ + Your query may not match anything in the current time range, or there may not be any data at all in the currently selected time range. Try change time range, query filters or choose different time fields + +

+
+ +
+ + + + + +
`; diff --git a/public/components/event_analytics/explorer/__tests__/__snapshots__/data_grid.test.tsx.snap b/public/components/event_analytics/explorer/__tests__/__snapshots__/data_grid.test.tsx.snap index e21e9494f..a0e63ed20 100644 --- a/public/components/event_analytics/explorer/__tests__/__snapshots__/data_grid.test.tsx.snap +++ b/public/components/event_analytics/explorer/__tests__/__snapshots__/data_grid.test.tsx.snap @@ -220,225 +220,217 @@ exports[`Datagrid component Renders data grid component 1`] = ` timeStampField="timestamp" totalHits={1390} > - -
-
- - - +
-
- -
-
-
- -
- +
- - - -
-
- +
+ + + + + +
`; diff --git a/public/components/event_analytics/explorer/datasources/datasources_selection.tsx b/public/components/event_analytics/explorer/datasources/datasources_selection.tsx index 3c6e34df1..5d4fe5f9a 100644 --- a/public/components/event_analytics/explorer/datasources/datasources_selection.tsx +++ b/public/components/event_analytics/explorer/datasources/datasources_selection.tsx @@ -3,14 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { useCallback, useContext, useEffect, useState, useMemo } from 'react'; +import React, { useCallback, useContext, useEffect, useState } from 'react'; import { batch, useDispatch, useSelector } from 'react-redux'; import { LogExplorerRouterContext } from '../..'; -import { - DataSourceGroup, - DataSourceSelectable, - DataSourceType, -} from '../../../../../../../src/plugins/data/public'; +import { DataSourceSelectable } from '../../../../../../../src/plugins/data/public'; import { coreRefs } from '../../../../framework/core_refs'; import { selectSearchMetaData, @@ -22,208 +18,109 @@ import { reset as resetPatterns } from '../../redux/slices/patterns_slice'; import { reset as resetQueryResults } from '../../redux/slices/query_result_slice'; import { reset as resetVisualization } from '../../redux/slices/visualization_slice'; import { reset as resetVisConfig } from '../../redux/slices/viualization_config_slice'; -import { reset as resetQuery } from '../../redux/slices/query_slice'; -import { DirectQueryRequest, SelectedDataSource } from '../../../../../common/types/explorer'; -import { ObservabilityDefaultDataSource } from '../../../../framework/datasources/obs_opensearch_datasource'; -import { - DATA_SOURCE_TYPE_URL_PARAM_KEY, - DATA_SOURCE_NAME_URL_PARAM_KEY, - DEFAULT_DATA_SOURCE_NAME, - DEFAULT_DATA_SOURCE_TYPE, - DEFAULT_DATA_SOURCE_TYPE_NAME, - DEFAULT_DATA_SOURCE_OBSERVABILITY_DISPLAY_NAME, - DATA_SOURCE_TYPES, - QUERY_LANGUAGE, -} from '../../../../../common/constants/data_sources'; -import { SQLService } from '../../../../services/requests/sql'; -import { get as getObjValue } from '../../../../../common/utils/shared'; -import { - setAsyncSessionId, - getAsyncSessionId, -} from '../../../../../common/utils/query_session_utils'; -import { DIRECT_DUMMY_QUERY } from '../../../../../common/constants/shared'; - -const getDataSourceState = (selectedSourceState: SelectedDataSource[]) => { - if (selectedSourceState.length === 0) return []; - return [ - { - label: selectedSourceState[0].label, - value: selectedSourceState[0].value, - type: selectedSourceState[0].type, - name: selectedSourceState[0].name, - }, - ]; -}; - -const removeDataSourceFromURLParams = (currURL: string) => { - // Parse the current URL - const currentURL = new URL(currURL); - - // Split the hash into its base and query parts - const [hashBase, hashQuery] = currentURL.hash.split('?'); - - if (hashQuery) { - // Convert the hash query into a URLSearchParams object for easier manipulation - const hashParams = new URLSearchParams(hashQuery); - - // Remove the data source redirection parameters - hashParams.delete(DATA_SOURCE_NAME_URL_PARAM_KEY); - hashParams.delete(DATA_SOURCE_TYPE_URL_PARAM_KEY); - - // Reconstruct the hash - currentURL.hash = hashParams.toString() ? `${hashBase}?${hashParams.toString()}` : hashBase; - // Update the browser's address bar - history.replaceState({}, '', currentURL.toString()); - } -}; - -export const DataSourceSelection = ({ tabId }: { tabId: string }) => { - const { dataSources, http } = coreRefs; - const sqlService = new SQLService(http!); +export const DataSourceSelection = ({ tabId }) => { + const { dataSources } = coreRefs; const dispatch = useDispatch(); const routerContext = useContext(LogExplorerRouterContext); const explorerSearchMetadata = useSelector(selectSearchMetaData)[tabId]; - const [activeDataSources, setActiveDataSources] = useState([]); - const [dataSourceOptionList, setDataSourceOptionList] = useState([]); - const [selectedSources, setSelectedSources] = useState( - getDataSourceState(explorerSearchMetadata.datasources) - ); - - /** - * Resets various states associated with data source changes. - */ - const resetStateOnDataSourceChange = () => { - dispatch(resetQuery({ tabId })); - dispatch(resetFields({ tabId })); - dispatch(resetFields({ tabId })); - dispatch(resetPatterns({ tabId })); - dispatch(resetQueryResults({ tabId })); - dispatch(resetVisConfig({ tabId })); - dispatch(resetVisualization({ tabId })); - dispatch(resetCountDistribution({ tabId })); + const [activeDataSources, setActiveDataSources] = useState([]); + const [dataSourceOptionList, setDataSourceOptionList] = useState([]); + const [selectedSources, setSelectedSources] = useState([...explorerSearchMetadata.datasources]); + + const resetStateOnDatasourceChange = () => { + dispatch( + resetFields({ + tabId, + }) + ); + dispatch( + resetPatterns({ + tabId, + }) + ); + dispatch( + resetQueryResults({ + tabId, + }) + ); + dispatch( + resetVisConfig({ + tabId, + }) + ); + dispatch( + resetVisualization({ + tabId, + }) + ); + dispatch( + resetCountDistribution({ + tabId, + }) + ); }; - /** - * Handle the changes in the data source selection. - * - * @param {SelectedDataSource[]} selectedSource - The newly selected data source(s). - */ - const handleSourceChange = (selectedSource: SelectedDataSource[]) => { + const handleSourceChange = (selectedSource) => { batch(() => { - resetStateOnDataSourceChange(); + resetStateOnDatasourceChange(); dispatch( - updateSearchMetaData({ tabId, data: { datasources: getDataSourceState(selectedSource) } }) + updateSearchMetaData({ + tabId, + data: { + datasources: selectedSource, + }, + }) ); }); setSelectedSources(selectedSource); }; - const runDummyQuery = (dataSource: string) => { - const requestPayload = { - lang: QUERY_LANGUAGE.SQL.toLowerCase(), - query: DIRECT_DUMMY_QUERY, - datasource: dataSource, - } as DirectQueryRequest; - - sqlService - .fetch(requestPayload) - .then((result) => { - setAsyncSessionId(getObjValue(result, 'sessionId', null)); - }) - .catch((e) => { - console.error(e); - }); - }; - useEffect(() => { - setSelectedSources(getDataSourceState(explorerSearchMetadata.datasources)); + setSelectedSources([...(explorerSearchMetadata.datasources || [])]); + return () => {}; }, [explorerSearchMetadata.datasources]); const handleDataSetFetchError = useCallback(() => { - return (error: Error) => { - console.error('Error fetching dataset:', error); - }; + return (error) => {}; }, []); - /** - * Subscribe to data source updates and manage the active data sources state. - */ useEffect(() => { const subscription = dataSources.dataSourceService.dataSources$.subscribe( (currentDataSources) => { - // temporary solution for 2.11 to render OpenSearch / default cluster for observability - // local indices and index patterns, while keep listing all index patterns for data explorer - // it filters the registered index pattern data sources in data plugin, and attach default cluster - // for all indices - setActiveDataSources([ - new ObservabilityDefaultDataSource({ - name: DEFAULT_DATA_SOURCE_NAME, - type: DEFAULT_DATA_SOURCE_TYPE, - metadata: null, - }), - ...Object.values(currentDataSources).filter((ds) => ds.type !== DEFAULT_DATA_SOURCE_TYPE), - ]); + setActiveDataSources([...Object.values(currentDataSources)]); } ); return () => subscription.unsubscribe(); }, []); - /** - * Check for URL parameters to update the data source if redirected from discover. - * Removes data source name and type from URL after processing. This is temporary solution for 2.11 - * as observability log explorer will adopt view service. - */ useEffect(() => { - const datasourceName = routerContext?.searchParams.get(DATA_SOURCE_NAME_URL_PARAM_KEY); - const datasourceType = routerContext?.searchParams.get(DATA_SOURCE_TYPE_URL_PARAM_KEY); + // update datasource if url contains + const datasourceName = routerContext?.searchParams.get('datasourceName'); + const datasourceType = routerContext?.searchParams.get('datasourceType'); if (datasourceName && datasourceType) { - // remove datasourceName and datasourceType from URL for a clean search state - removeDataSourceFromURLParams(window.location.href); - batch(() => { - resetStateOnDataSourceChange(); - dispatch( - updateSearchMetaData({ - tabId, - data: { datasources: [{ label: datasourceName, type: datasourceType }] }, - }) - ); - }); + dispatch( + updateSearchMetaData({ + tabId, + data: { + datasources: [ + { + label: datasourceName, + type: datasourceType, + }, + ], + }, + }) + ); } }, []); - useEffect(() => { - // Execute a dummy query to initialize the cluster and obtain a sessionId for subsequent queries. - const dsType = explorerSearchMetadata.datasources?.[0]?.type; - const dsName = explorerSearchMetadata.datasources?.[0]?.label; - if ( - !getAsyncSessionId() && - [DATA_SOURCE_TYPES.SPARK, DATA_SOURCE_TYPES.S3Glue].includes(dsType) && - dsName - ) { - runDummyQuery(dsName); - } - }, [explorerSearchMetadata.datasources]); - - /** - * Process the data source options to display different than discover's group names. - * Temporary solution for version 2.11. - */ - const memorizedDataSourceOptionList = useMemo(() => { - return dataSourceOptionList.map((dsOption) => { - if (dsOption.label === DEFAULT_DATA_SOURCE_TYPE_NAME) { - dsOption.label = DEFAULT_DATA_SOURCE_OBSERVABILITY_DISPLAY_NAME; - } - return dsOption; - }); - }, [dataSourceOptionList]); - return ( { - const explorerSearchMeta = useSelector(selectSearchMetaData)[tabId] || {}; const dispatch = useDispatch(); - const sqlService = new SQLService(coreRefs.http); - - const cancelQuery = () => { - if (explorerSearchMeta.queryId) { - sqlService.deleteWithJobId({ queryId: explorerSearchMeta.queryId }).catch((e) => { - console.error(e); - }); - } - - // reset isPolling flag to remove loading page and queryId to empty - dispatch( - updateSearchMetaData({ - tabId, - data: { - isPolling: false, - queryId: '', - }, - }) - ); - }; - return ( } title={

Query Processing

} body={ - <> - - Status: {explorerSearchMeta.status ?? DirectQueryLoadingStatus.SCHEDULED} - - - - Cancel - - + { + dispatch( + updateSearchMetaData({ + tabId, + data: { + isPolling: false, + }, + }) + ); + }} + > + Cancel + } /> ); diff --git a/public/components/event_analytics/explorer/events_views/data_grid.scss b/public/components/event_analytics/explorer/events_views/data_grid.scss index af387c2cd..bf5392d3b 100644 --- a/public/components/event_analytics/explorer/events_views/data_grid.scss +++ b/public/components/event_analytics/explorer/events_views/data_grid.scss @@ -225,6 +225,9 @@ // SASSTODO: replace the z-index value with a variable .dscWrapper { + padding-left: $euiSizeXL; + padding-right: $euiSizeS; + margin-top: $euiSizeM; z-index: 1; @include euiBreakpoint('xs', 's', 'm') { padding-left: $euiSizeS; diff --git a/public/components/event_analytics/explorer/events_views/data_grid.tsx b/public/components/event_analytics/explorer/events_views/data_grid.tsx index 56cac6abb..f6019d42b 100644 --- a/public/components/event_analytics/explorer/events_views/data_grid.tsx +++ b/public/components/event_analytics/explorer/events_views/data_grid.tsx @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { useMemo, useState, useRef, Fragment, useCallback } from 'react'; +import React, { useMemo, useState, useRef, RefObject, Fragment, useCallback } from 'react'; import { EuiDataGrid, EuiDescriptionList, @@ -11,21 +11,26 @@ import { EuiDescriptionListTitle, EuiDataGridColumn, EuiDataGridSorting, - EuiPanel, } from '@elastic/eui'; import moment from 'moment'; +import dompurify from 'dompurify'; +import datemath from '@elastic/datemath'; import { MutableRefObject } from 'react'; -import { IExplorerFields, IField } from '../../../../../common/types/explorer'; +import { GridSortingColumn, IExplorerFields, IField } from '../../../../../common/types/explorer'; import { DATE_DISPLAY_FORMAT, - DEFAULT_EMPTY_EXPLORER_FIELDS, + DATE_PICKER_FORMAT, DEFAULT_SOURCE_COLUMN, DEFAULT_TIMESTAMP_COLUMN, } from '../../../../../common/constants/explorer'; import { HttpSetup } from '../../../../../../../src/core/public'; import PPLService from '../../../../services/requests/ppl'; -import { FlyoutButton } from './docViewRow'; +import { FlyoutButton, IDocType } from './docViewRow'; import { useFetchEvents } from '../../hooks'; +import { + PPL_INDEX_INSERT_POINT_REGEX, + PPL_NEWLINE_REGEX, +} from '../../../../../common/constants/shared'; import { redoQuery } from '../../utils/utils'; interface DataGridProps { @@ -56,76 +61,55 @@ export function DataGrid(props: DataGridProps) { requestParams, startTime, endTime, + storedSelectedColumns, } = props; - const { fetchEvents } = useFetchEvents({ + const { getEvents } = useFetchEvents({ pplService, requestParams, }); - const selectedColumns = - explorerFields.selectedFields.length > 0 - ? explorerFields.selectedFields - : DEFAULT_EMPTY_EXPLORER_FIELDS; // useRef instead of useState somehow solves the issue of user triggered sorting not // having any delays const sortingFields: MutableRefObject = useRef([]); const pageFields = useRef([0, 100]); - const [data, setData] = useState(rows); - // setSort and setPage are used to change the query and send a direct request to get data const setSort = (sort: EuiDataGridSorting['columns']) => { sortingFields.current = sort; - - redoQuery( - startTime, - endTime, - rawQuery, - timeStampField, - sortingFields, - pageFields, - fetchEvents, - setData - ); + redoQuery(startTime, endTime, rawQuery, timeStampField, sortingFields, pageFields, getEvents); }; const setPage = (page: number[]) => { pageFields.current = page; - redoQuery( - startTime, - endTime, - rawQuery, - timeStampField, - sortingFields, - pageFields, - fetchEvents, - setData - ); + redoQuery(startTime, endTime, rawQuery, timeStampField, sortingFields, pageFields, getEvents); }; // creates the header for each column listing what that column is const dataGridColumns = useMemo(() => { - const columns: EuiDataGridColumn[] = []; - selectedColumns.map(({ name, type }) => { - if (name === 'timestamp') { - columns.push(DEFAULT_TIMESTAMP_COLUMN); - } else if (name === '_source') { - columns.push(DEFAULT_SOURCE_COLUMN); - } else { - columns.push({ - id: name, - display: name, - isSortable: true, // TODO: add functionality here based on type - }); - } - }); - return columns; - }, [explorerFields, totalHits]); + if (storedSelectedColumns.length > 0) { + const columns: EuiDataGridColumn[] = []; + storedSelectedColumns.map(({ name, type }) => { + if (name === 'timestamp') { + columns.push(DEFAULT_TIMESTAMP_COLUMN); + } else if (name === '_source') { + columns.push(DEFAULT_SOURCE_COLUMN); + } else { + columns.push({ + id: name, + display: name, + isSortable: true, // TODO: add functionality here based on type + }); + } + }); + return columns; + } + return []; + }, [storedSelectedColumns]); // used for which columns are visible and their order const dataGridColumnVisibility = useMemo(() => { - if (selectedColumns.length > 0) { + if (storedSelectedColumns.length > 0) { const columns: string[] = []; - selectedColumns.map(({ name }) => { + storedSelectedColumns.map(({ name }) => { columns.push(name); }); return { @@ -137,7 +121,7 @@ export function DataGrid(props: DataGridProps) { } // default shown fields throw new Error('explorer data grid stored columns empty'); - }, [explorerFields, totalHits]); + }, [storedSelectedColumns]); // sets the very first column, which is the button used for the flyout of each row const dataGridLeadingColumns = useMemo(() => { @@ -171,23 +155,23 @@ export function DataGrid(props: DataGridProps) { width: 40, }, ]; - }, [rows, http, explorerFields, pplService, rawQuery, timeStampField, totalHits]); + }, [rows, http, explorerFields, pplService, rawQuery, timeStampField]); // renders what is shown in each cell, i.e. the content of each row const dataGridCellRender = useCallback( ({ rowIndex, columnId }: { rowIndex: number; columnId: string }) => { const trueIndex = rowIndex % pageFields.current[1]; - if (trueIndex < data.length) { + if (trueIndex < rows.length) { if (columnId === '_source') { return ( - {Object.keys(data[trueIndex]).map((key) => ( + {Object.keys(rows[trueIndex]).map((key) => ( {key} - {data[trueIndex][key]} + {rows[trueIndex][key]} ))} @@ -195,13 +179,13 @@ export function DataGrid(props: DataGridProps) { ); } if (columnId === 'timestamp') { - return `${moment(data[trueIndex][columnId]).format(DATE_DISPLAY_FORMAT)}`; + return `${moment(rows[trueIndex][columnId]).format(DATE_DISPLAY_FORMAT)}`; } - return `${data[trueIndex][columnId]}`; + return `${rows[trueIndex][columnId]}`; } return null; }, - [data, rows, pageFields, explorerFields, totalHits] + [rows, pageFields, explorerFields] ); // ** Pagination config @@ -213,7 +197,7 @@ export function DataGrid(props: DataGridProps) { setPage([0, pageSize]); return { pageIndex: 0, pageSize }; }), - [setPagination, setPage, totalHits] + [setPagination, setPage] ); // changing the page index, keep page size constant const onChangePage = useCallback( @@ -223,23 +207,23 @@ export function DataGrid(props: DataGridProps) { return { pageSize, pageIndex }; }); }, - [setPagination, setPage, totalHits] + [setPagination, setPage] ); const rowHeightsOptions = useMemo( () => ({ defaultHeight: { // if source is listed as a column, add extra space - lineCount: selectedColumns.some((obj) => obj.name === '_source') ? 3 : 1, + lineCount: storedSelectedColumns.some((obj) => obj.name === '_source') ? 3 : 1, }, }), - [explorerFields, totalHits] + [storedSelectedColumns] ); // TODO: memoize the expensive table below return ( - + <>
-
+ ); } diff --git a/public/components/event_analytics/explorer/events_views/docView.scss b/public/components/event_analytics/explorer/events_views/docView.scss index f05023e21..c395ed4da 100644 --- a/public/components/event_analytics/explorer/events_views/docView.scss +++ b/public/components/event_analytics/explorer/events_views/docView.scss @@ -37,8 +37,8 @@ .events-flyout-resize { position: absolute; - right: 38px; - top: 8px; + right: 30px; + top: 0px; z-index: 3; } diff --git a/public/components/event_analytics/explorer/events_views/doc_flyout.tsx b/public/components/event_analytics/explorer/events_views/doc_flyout.tsx index feb0a57e9..dc1629b71 100644 --- a/public/components/event_analytics/explorer/events_views/doc_flyout.tsx +++ b/public/components/event_analytics/explorer/events_views/doc_flyout.tsx @@ -85,7 +85,7 @@ export const DocFlyout = ({ { - return explorerSearchMeta.datasources?.[0]?.type - ? dataSourcePluggables[explorerSearchMeta?.datasources[0]?.type] - : dataSourcePluggables.DEFAULT_INDEX_PATTERNS; + return ( + dataSourcePluggables[explorerSearchMeta.datasources[0]?.type] || + dataSourcePluggables.DEFAULT_INDEX_PATTERNS + ); }, [explorerSearchMeta.datasources]); const { ui } = - currentPluggable?.getComponentSetForVariation( - 'languages', - explorerSearchMeta.lang || QUERY_LANGUAGE.SQL - ) || {}; + currentPluggable?.getComponentSetForVariation('languages', explorerSearchMeta.lang || 'SQL') || + {}; const SearchBar = ui?.SearchBar || Search; - const isDefaultDataSourceType = - explorerSearchMeta.datasources?.[0]?.type === DEFAULT_DATA_SOURCE_TYPE; + const selectedIntervalRef = useRef<{ text: string; value: string; @@ -223,8 +219,6 @@ export const Explorer = ({ const isLiveTailOnRef = useRef(false); const liveTailTabIdRef = useRef(''); const liveTailNameRef = useRef('Live'); - const savedObjectLoader = useRef(undefined); - const isObjectIdUpdatedFromSave = useRef(false); // Flag to prevent reload when the current search's objectId changes due to a save operation. queryRef.current = query; selectedPanelNameRef.current = selectedPanelName; explorerFieldsRef.current = explorerFields; @@ -258,12 +252,6 @@ export const Explorer = ({ ...TIME_INTERVAL_OPTIONS, ]); selectedIntervalRef.current = { text: 'Auto', value: 'auto_' + minInterval }; - dispatch( - updateCountDistribution({ - tabId, - data: { selectedInterval: selectedIntervalRef.current.value.replace(/^auto_/, '') }, - }) - ); }; useEffect(() => { @@ -323,7 +311,7 @@ export const Explorer = ({ !isEqual(getIndexPatternFromRawQuery(currentQuery), getIndexPatternFromRawQuery(prevTabQuery)); const updateTabData = async (objectId: string) => { - savedObjectLoader.current = new ExplorerSavedObjectLoader( + await new PPLSavedObjectLoader( getSavedObjectsClient({ objectId, objectType: 'savedQuery' }), notifications, { @@ -350,26 +338,10 @@ export const Explorer = ({ setSubType, setSelectedContentTab, fetchData, - dispatchOnGettingHis, } - ); - savedObjectLoader.current.load(); + ).load(); }; - // stop polling when cancel or unmounts - useEffect(() => { - const sol: ExplorerSavedObjectLoader | undefined = savedObjectLoader.current; - if (!explorerSearchMeta.isPolling && sol !== undefined && sol.getPollingInstance) { - sol?.getPollingInstance()!.stopPolling(); - savedObjectLoader.current = undefined; - } - return () => { - if (sol && sol.getPollingInstance) { - sol?.getPollingInstance()!.stopPolling(); - } - }; - }, [explorerSearchMeta.isPolling]); - const prepareAvailability = async () => { setSelectedContentTab(TAB_CHART_ID); setTriggerAvailability(true); @@ -399,9 +371,8 @@ export const Explorer = ({ }, []); useEffect(() => { - if (savedObjectId && !isObjectIdUpdatedFromSave.current) { + if (savedObjectId) { updateTabData(savedObjectId); - isObjectIdUpdatedFromSave.current = false; } }, [savedObjectId]); @@ -413,7 +384,10 @@ export const Explorer = ({ await dispatch( changeDateRange({ tabId: requestParams.tabId, - data: { [RAW_QUERY]: queryRef.current![RAW_QUERY], [SELECTED_DATE_RANGE]: timeRange }, + data: { + [RAW_QUERY]: queryRef.current![RAW_QUERY], + [SELECTED_DATE_RANGE]: timeRange, + }, }) ); }; @@ -449,13 +423,48 @@ export const Explorer = ({ } }; + useEffect(() => { + if (explorerSearchMeta.datasources?.[0]?.type !== 'DEFAULT_INDEX_PATTERNS') { + dispatch( + changeQuery({ + tabId, + query: { + [RAW_QUERY]: '', + [FINAL_QUERY]: '', + }, + }) + ); + } + }, [explorerSearchMeta.datasources]); + const handleOverrideTimestamp = async (timestamp: IField) => { setIsOverridingTimestamp(true); - await dispatch(changeQuery({ tabId, query: { [SELECTED_TIMESTAMP]: timestamp?.name || '' } })); + await dispatch( + changeQuery({ + tabId, + query: { + [SELECTED_TIMESTAMP]: timestamp?.name || '', + }, + }) + ); setIsOverridingTimestamp(false); handleQuerySearch(); }; + const handleOverridePattern = async (pattern: IField) => { + setIsOverridingPattern(true); + await setDefaultPatternsField( + '', + pattern.name, + getErrorHandler('Error overriding default pattern') + ); + setIsOverridingPattern(false); + await getPatterns( + selectedIntervalRef.current?.value.replace(/^auto_/, '') || 'y', + getErrorHandler('Error fetching patterns') + ); + }; + const totalHits: number = useMemo(() => { if (isLiveTailOn && countDistribution?.data) { const hits = reduce( @@ -472,18 +481,22 @@ export const Explorer = ({ }, [countDistribution?.data]); const dateRange = getDateRange(startTime, endTime, query); + + const [storedExplorerFields, setStoredExplorerFields] = useState(explorerFields); + const mainContent = useMemo(() => { return ( -
+
{explorerData && !isEmpty(explorerData.jsonData) ? ( - {(isDefaultDataSourceType || appLogEvents) && ( + {explorerSearchMeta.datasources?.[0]?.type === 'DEFAULT_INDEX_PATTERNS' && ( + {/* */} {countDistribution?.data && !isLiveTailOnRef.current && ( - + <> {}} /> @@ -494,34 +507,26 @@ export const Explorer = ({ (item) => item.value === selectedIntrv ); const intrv = selectedIntrv.replace(/^auto_/, ''); - dispatch( - updateCountDistribution({ tabId, data: { selectedInterval: intrv } }) - ); getCountVisualizations(intrv); selectedIntervalRef.current = timeIntervalOptions[intervalOptionsIndex]; getPatterns(intrv, getErrorHandler('Error fetching patterns')); }} - stateInterval={ - countDistribution.selectedInterval || selectedIntervalRef.current?.value - } + stateInterval={selectedIntervalRef.current?.value} startTime={appLogEvents ? startTime : dateRange[0]} endTime={appLogEvents ? endTime : dateRange[1]} /> - - + )} )} - {(isDefaultDataSourceType || appLogEvents) && ( + {explorerSearchMeta.datasources?.[0]?.type === 'DEFAULT_INDEX_PATTERNS' && ( @@ -563,26 +568,25 @@ export const Explorer = ({ )} - {(countDistribution.data?.['count()'] || explorerData?.datarows?.length) && ( - - )} + + 0 + ? storedExplorerFields.selectedFields + : DEFAULT_EMPTY_EXPLORER_FIELDS + } + /> @@ -600,11 +604,13 @@ export const Explorer = ({ isPanelTextFieldInvalid, explorerData, explorerFields, + isSidebarClosed, countDistribution, explorerVisualizations, isOverridingTimestamp, query, isLiveTailOnRef.current, + isOverridingPattern, isQueryRunning, ]); @@ -632,7 +638,7 @@ export const Explorer = ({ }; const explorerVis = useMemo(() => { - return isDefaultDataSourceType || appLogEvents ? ( + return explorerSearchMeta.datasources?.[0]?.type === 'DEFAULT_INDEX_PATTERNS' ? ( { await dispatch( - changeQuery({ tabId, query: { [RAW_QUERY]: updateQuery.replaceAll(PPL_NEWLINE_REGEX, '') } }) + changeQuery({ + tabId, + query: { + [RAW_QUERY]: updateQuery.replaceAll(PPL_NEWLINE_REGEX, ''), + }, + }) ); }; @@ -687,7 +698,14 @@ export const Explorer = ({ async (availability?: boolean) => { // clear previous selected timestamp when index pattern changes if (isIndexPatternChanged(tempQuery, query[RAW_QUERY])) { - await dispatch(changeQuery({ tabId, query: { [SELECTED_TIMESTAMP]: '' } })); + await dispatch( + changeQuery({ + tabId, + query: { + [SELECTED_TIMESTAMP]: '', + }, + }) + ); await setDefaultPatternsField('', ''); } if (availability !== true) { @@ -700,21 +718,26 @@ export const Explorer = ({ const handleQueryChange = async (newQuery: string) => setTempQuery(newQuery); + const getSavingCommonParams = ( + queryState: IQuery, + fields: IExplorerFields, + savingTitle: string + ) => { + return { + query: buildRawQuery(query, appBaseQuery), + fields: fields[SELECTED_FIELDS], + dateRange: queryState[SELECTED_DATE_RANGE], + name: savingTitle, + timestamp: queryState[SELECTED_TIMESTAMP], + }; + }; + const handleSavingObject = useCallback(() => { const isOnEventPage = isEqual(selectedContentTabId, TAB_EVENT_ID); const isObjTypeMatchQuery = isEqual(query[SAVED_OBJECT_TYPE], SAVED_QUERY); const isObjTypeMatchVis = isEqual(query[SAVED_OBJECT_TYPE], SAVED_VISUALIZATION); const isTabHasObjID = !isEmpty(query[SAVED_OBJECT_ID]); - const commonParams = getSavingCommonParams( - query, - appBaseQuery, - explorerFields, - selectedPanelNameRef.current, - explorerSearchMeta - ); - - // Set the flag to differentiate between an object save action and a load action - isObjectIdUpdatedFromSave.current = true; + const commonParams = getSavingCommonParams(query, explorerFields, selectedPanelNameRef.current); let soClient; if (isOnEventPage) { @@ -722,10 +745,7 @@ export const Explorer = ({ soClient = new SaveAsCurrentQuery( { tabId, notifications }, { dispatch, updateTabName }, - getSavedObjectsClient({ - objectId: query[SAVED_OBJECT_ID], - objectType: 'savedQuery', - }), + PPLSavedQueryClient.getInstance(), { ...commonParams, objectId: query[SAVED_OBJECT_ID], @@ -735,7 +755,7 @@ export const Explorer = ({ soClient = new SaveAsNewQuery( { tabId, history, notifications, showPermissionErrorToast }, { batch, dispatch, changeQuery, updateTabName }, - OSDSavedSearchClient.getInstance(), + new PPLSavedQueryClient(http), { ...commonParams } ); } @@ -793,11 +813,10 @@ export const Explorer = ({ explorerFields, subType, selectedCustomPanelOptions, - explorerSearchMeta, - selectedIntervalRef.current, - countDistribution, ]); + // live tail + const liveTailLoop = async ( name: string, startingTime: string, @@ -807,7 +826,7 @@ export const Explorer = ({ setLiveTailName(name); setLiveTailTabId((curSelectedTabId.current as unknown) as string); setIsLiveTailOn(true); - setToast('Live tail On', 'success', '', 'right', 2000); + setToast('Live tail On', 'success'); setIsLiveTailPopoverOpen(false); setLiveTimestamp( dateMath.parse(endingTime, { roundUp: true })?.utc().format(DATE_PICKER_FORMAT) || '' @@ -832,7 +851,7 @@ export const Explorer = ({ setIsLiveTailOn(false); setLiveHits(0); setIsLiveTailPopoverOpen(false); - if (isLiveTailOnRef.current) setToast('Live tail Off', 'danger', '', 'right', 2000); + if (isLiveTailOnRef.current) setToast('Live tail Off', 'danger'); }; useEffect(() => { @@ -894,89 +913,104 @@ export const Explorer = ({ handleQueryChange, }} > - - - - {!appLogEvents && ( - - - - )} - - - - - - -
- +
+ + + + +
+ +
+
- - handleTimePickerChange(timeRange) - } - selectedPanelName={selectedPanelNameRef.current} - selectedCustomPanelOptions={selectedCustomPanelOptions} - setSelectedPanelName={setSelectedPanelName} - setSelectedCustomPanelOptions={setSelectedCustomPanelOptions} - handleSavingObject={handleSavingObject} - isPanelTextFieldInvalid={isPanelTextFieldInvalid} - savedObjects={savedObjects} - showSavePanelOptionsList={isEqual(selectedContentTabId, TAB_CHART_ID)} - handleTimeRangePickerRefresh={handleTimeRangePickerRefresh} - isLiveTailPopoverOpen={isLiveTailPopoverOpen} - closeLiveTailPopover={() => setIsLiveTailPopoverOpen(false)} - popoverItems={popoverItems} - isLiveTailOn={isLiveTailOnRef.current} - selectedSubTabId={selectedContentTabId} - searchBarConfigs={searchBarConfigs} - getSuggestions={parseGetSuggestions} - onItemSelect={onItemSelect} - tabId={tabId} - baseQuery={appBaseQuery} - stopLive={stopLive} - setIsLiveTailPopoverOpen={setIsLiveTailPopoverOpen} - liveTailName={liveTailNameRef.current} - curVisId={curVisId} - setSubType={setSubType} - http={http} - setIsQueryRunning={setIsQueryRunning} - /> - {explorerSearchMeta.isPolling ? ( - - ) : ( - tab.id === selectedContentTabId)} - onTabClick={(selectedTab: EuiTabbedContentTab) => - handleContentTabClick(selectedTab) +
+ 0 + ? storedExplorerFields + : explorerFields + } + setStoredExplorerFields={setStoredExplorerFields} /> - )} +
-
- - + + + handleTimePickerChange(timeRange)} + selectedPanelName={selectedPanelNameRef.current} + selectedCustomPanelOptions={selectedCustomPanelOptions} + setSelectedPanelName={setSelectedPanelName} + setSelectedCustomPanelOptions={setSelectedCustomPanelOptions} + handleSavingObject={handleSavingObject} + isPanelTextFieldInvalid={isPanelTextFieldInvalid} + savedObjects={savedObjects} + showSavePanelOptionsList={isEqual(selectedContentTabId, TAB_CHART_ID)} + handleTimeRangePickerRefresh={handleTimeRangePickerRefresh} + isLiveTailPopoverOpen={isLiveTailPopoverOpen} + closeLiveTailPopover={() => setIsLiveTailPopoverOpen(false)} + popoverItems={popoverItems} + isLiveTailOn={isLiveTailOnRef.current} + selectedSubTabId={selectedContentTabId} + searchBarConfigs={searchBarConfigs} + getSuggestions={parseGetSuggestions} + onItemSelect={onItemSelect} + tabId={tabId} + baseQuery={appBaseQuery} + stopLive={stopLive} + setIsLiveTailPopoverOpen={setIsLiveTailPopoverOpen} + liveTailName={liveTailNameRef.current} + curVisId={curVisId} + setSubType={setSubType} + http={http} + setIsQueryRunning={setIsQueryRunning} + /> + {explorerSearchMeta.isPolling ? ( + + ) : ( + tab.id === selectedContentTabId)} + onTabClick={(selectedTab: EuiTabbedContentTab) => + handleContentTabClick(selectedTab) + } + tabs={contentTabs} + size="s" + /> + )} + +
+
); }; diff --git a/public/components/event_analytics/explorer/log_explorer.tsx b/public/components/event_analytics/explorer/log_explorer.tsx index 37296e266..05bd47544 100644 --- a/public/components/event_analytics/explorer/log_explorer.tsx +++ b/public/components/event_analytics/explorer/log_explorer.tsx @@ -4,7 +4,6 @@ */ /* eslint-disable react-hooks/exhaustive-deps */ import { isEmpty } from 'lodash'; -import { EuiPage } from '@elastic/eui'; import React, { useContext, useEffect, useRef, useState } from 'react'; import { useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; diff --git a/public/components/event_analytics/explorer/no_results.tsx b/public/components/event_analytics/explorer/no_results.tsx index d6c96af86..91cc8ab62 100644 --- a/public/components/event_analytics/explorer/no_results.tsx +++ b/public/components/event_analytics/explorer/no_results.tsx @@ -4,44 +4,48 @@ */ import React from 'react'; -import { FormattedMessage } from '@osd/i18n/react'; -import { EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiPage, EuiSpacer, EuiText } from '@elastic/eui'; +import { FormattedMessage, I18nProvider } from '@osd/i18n/react'; +import { EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui'; export const NoResults = () => { return ( - - - - - } - color="warning" - iconType="help" - data-test-subj="observabilityNoResultsCallout" - /> - - - - -

- -

-

- -

-
-
-
-
+ + <> + + + + + + } + color="warning" + iconType="help" + data-test-subj="discoverNoResults" + /> + <> + + +

+ +

+

+ +

+
+ +
+
+ +
); }; diff --git a/public/components/event_analytics/explorer/sidebar/__tests__/__snapshots__/field.test.tsx.snap b/public/components/event_analytics/explorer/sidebar/__tests__/__snapshots__/field.test.tsx.snap index 7f7e730cc..0abf095fc 100644 --- a/public/components/event_analytics/explorer/sidebar/__tests__/__snapshots__/field.test.tsx.snap +++ b/public/components/event_analytics/explorer/sidebar/__tests__/__snapshots__/field.test.tsx.snap @@ -1,102 +1,208 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Field component Renders a sidebar field 1`] = ` - - + + + + Override + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ AGENT +

+
+
+ + String + +
+ +
+
+ + + + + + + } + fieldIcon={ + } - handleOverrideTimestamp={[MockFunction]} - isFieldToggleButtonDisabled={false} - isOverridingTimestamp={false} - onToggleField={[MockFunction]} - selected={true} - selectedTimestamp="timestamp" - showTimestampOverrideButton={true} - showToggleButton={true} - tabId="DEFAULT_INDEX_PATTERNS" + fieldName={ + + + agent + + + } + isActive={false} + onClick={[Function]} + size="s" > - -
- -
- - - - - - - - - - - -
-
- + + + + + + + -
-
-
+ + + +
- -
- -
-
+ + + + +
- -
- + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" > - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} - onBlur={[Function]} - onFocus={[Function]} - ownFocus={true} - panelClassName="explorerSidebarItem__fieldPopoverPanel" - panelPaddingSize="m" +
-
-
- -
-
- - - -
- - + + + + +
+
+ + + + -
- - - - - -
- + + + + + + +
-
-
-
+
+ + `; diff --git a/public/components/event_analytics/explorer/sidebar/__tests__/__snapshots__/sidebar.test.tsx.snap b/public/components/event_analytics/explorer/sidebar/__tests__/__snapshots__/sidebar.test.tsx.snap index 28c6cd812..fae58502a 100644 --- a/public/components/event_analytics/explorer/sidebar/__tests__/__snapshots__/sidebar.test.tsx.snap +++ b/public/components/event_analytics/explorer/sidebar/__tests__/__snapshots__/sidebar.test.tsx.snap @@ -163,149 +163,107 @@ exports[`Siderbar component Renders empty sidebar component 1`] = ` } } > - <_EuiSplitPanelOuter - borderRadius="none" - className="sidebar-list eui-yScroll" - color="transparent" +
- -
- <_EuiSplitPanelInner - grow={false} - paddingSize="s" + -
-
- + + + +
- -
- -
-
- -
+ + + + + +
+
-
- - <_EuiSplitPanelInner - className="eui-yScroll" - paddingSize="none" - > - -
- - -
-
- +
+ + +
+ +
+ +
+ @@ -701,7 +659,6 @@ exports[`Siderbar component Renders sidebar component 1`] = ` "unselectedFields": Array [], } } - tabId="DEFAULT_INDEX_PATTERNS" > - <_EuiSplitPanelOuter - borderRadius="none" - className="sidebar-list eui-yScroll" - color="transparent" +
- -
- <_EuiSplitPanelInner - grow={false} - paddingSize="s" + -
-
- + + + +
- -
- -
-
- -
+ + + + + + +
+
-
- - <_EuiSplitPanelInner - className="eui-yScroll" - paddingSize="none" +
+ + +
+ +
+ +
+ + + Query fields + + + } + id="fieldSelector__queriedFields" + initialIsOpen={true} + isLoading={false} + isLoadingMessage={false} + paddingSize="xs" + > +
- -
- -

- - Query fields - -

-
- + + + + - + + Query fields + + + + +
+
+ +
+
- +
+ + -
- - - - - -
-
- + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ DOUBLE_PER_IP_BYTES +

+
+
+ + Long + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + double_per_ip_bytes + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- double_per_ip_bytes -
-
-
-
- - - - + - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + className="osdFieldButton__name" + > + + +
+ double_per_ip_bytes +
+
+
+
+ +
+ + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
- +
- -
- - - - - - - - + + + + + - - -
-
- + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ HOST +

+
+
+ + Text + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + host + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- host -
-
-
-
- - - - + - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + className="osdFieldButton__name" + > + + +
+ host +
+
+
+
+ +
+ + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
- +
- -
- - - - - - - - + + + + + - - -
-
- + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ IP_COUNT +

+
+
+ + Integer + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + ip_count + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- ip_count -
-
-
-
- - - - + - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + className="osdFieldButton__name" + > + + +
+ ip_count +
+
+
+
+ +
+ + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
- +
- -
- - - - - - - - + + + + + - - -
-
- + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ PER_IP_BYTES +

+
+
+ + Long + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + per_ip_bytes + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- per_ip_bytes -
-
-
-
- - - - + - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + className="osdFieldButton__name" + > + + +
+ per_ip_bytes +
+
+
+
+ +
+ + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
- +
- -
- - - - - - - - + + + + + - - -
-
- + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ RESP_CODE +

+
+
+ + Text + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + resp_code + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- resp_code -
-
-
-
- - - - + - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + className="osdFieldButton__name" + > + + +
+ resp_code +
+
+
+
+ +
+ + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
- +
- -
- - - - - - - - + + + + + - - -
-
- + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ SUM_BYTES +

+
+
+ + Long + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + sum_bytes + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- sum_bytes -
-
-
-
- - - - + - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + className="osdFieldButton__name" + > + + +
+ sum_bytes +
+
+
+
+ +
+ + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
- +
- -
- - - - - -
- -
-
- - - - +
+ + +
+
+ +
+
+ + + +
+
+ +
+
+ + +
+ + + + Selected Fields + + + } + id="fieldSelector__selectedFields" + initialIsOpen={true} + isLoading={false} + isLoadingMessage={false} + paddingSize="xs" + > +
+
+ +
+
+ +
+
- +
+ + -
-
- -
-
-
- - - +
+ +
+
+ + + +
+
+ +
+
+ + +
+ + + + Available Fields + + + } + id="fieldSelector__availableFields" + initialIsOpen={true} + isLoading={false} + isLoadingMessage={false} + paddingSize="xs" + > +
+
+ +
+
+ +
+
- +
+ + -
- - - - - -
-
- + + + + Override + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ AGENT +

+
+
+ + String + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + agent + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- agent -
-
-
-
- + - -
- + agent +
+ +
+ + +
+ + + + - -
- - -
- - - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
-
+
-
-
-
-
-
-
-
- - - + + + + + - - -
-
- + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ BYTES +

+
+
+ + Long + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + bytes + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- bytes -
-
-
-
- - - - + - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + className="osdFieldButton__name" + > + + +
+ bytes +
+
+
+
+ +
+ + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
- +
- -
- - - - - - - - + + + + + - - -
-
- + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ CLIENTIP +

+
+
+ + Ip + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + clientip + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- clientip -
-
-
-
- - - - + - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + className="osdFieldButton__name" + > + + +
+ clientip +
+
+
+
+ +
+ + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
- +
- -
- - - - - - - - + + + + + - - -
-
- + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ EVENT +

+
+
+ + Struct + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + event + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- event -
-
-
-
- - - - + - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + className="osdFieldButton__name" + > + + +
+ event +
+
+
+
+ +
+ + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
- +
- -
- - - - - - - - + + + + + - - -
-
- + + + + Override + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ EXTENSION +

+
+
+ + String + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + extension + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- extension -
-
-
-
- + - -
- + extension +
+ +
+ + +
+ + + + - -
- - -
- - - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
-
+
-
-
-
-
- - -
- - - + + + + + - - -
-
- + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ GEO +

+
+
+ + Struct + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + geo + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- geo -
-
-
-
- - - - + - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + className="osdFieldButton__name" + > + + +
+ geo +
+
+
+
+ +
+ + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
- +
- -
- - - - - - - - + + + + + - - -
-
- + + + + Override + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ HOST +

+
+
+ + String + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + host + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- host -
-
-
-
- + - -
- + host +
+ +
+ + +
+ + + + - -
- - -
- - - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
-
+
-
-
-
-
- - -
- - - + + + + + - - -
-
- + + + + Override + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ INDEX +

+
+
+ + String + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + index + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- index -
-
-
-
- + - -
- + index +
+ +
+ + +
+ + + + - -
- - -
- - - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
-
+
-
-
-
-
- - -
- - - + + + + + - - -
-
- + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ IP +

+
+
+ + Ip + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + ip + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- ip -
-
-
-
- - - - + - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + className="osdFieldButton__name" + > + + +
+ ip +
+
+
+
+ +
+ + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
- +
- -
- - - - - - - - + + + + + - - -
-
- + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ MACHINE +

+
+
+ + Struct + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + machine + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- machine -
-
-
-
- - - - + - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + className="osdFieldButton__name" + > + + +
+ machine +
+
+
+
+ +
+ + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
- +
- -
- - - - - - - - + + + + + - - -
-
- -
- -
+ - + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ MEMORY +

+
+
+ + Double + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + memory + + + } + isActive={false} + onClick={[Function]} + size="s" + > +
+
- - -
- -
- memory -
-
-
-
- - - - + - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + className="osdFieldButton__name" + > + + +
+ memory +
+
+
+
+ +
+ + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
- +
- -
- - - - - - - - + + + + + - - -
-
- + + + + Override + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ MESSAGE +

+
+
+ + String + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + message + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- message -
-
-
-
- + - -
- + message +
+ +
+ + +
+ + + + - -
- - -
- - - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
-
+
-
-
-
-
- - -
- - - + + + + + - - -
-
- + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ PHPMEMORY +

+
+
+ + Long + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + phpmemory + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- phpmemory -
-
-
-
- - - - + - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + className="osdFieldButton__name" + > + + +
+ phpmemory +
+
+
+
+ +
+ + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
- +
- -
- - - - - - - - + + + + + - - -
-
- + + + + Override + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ REFERER +

+
+
+ + String + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + referer + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- referer -
-
-
-
- + - -
- + referer +
+ +
+ + +
+ + + + - -
- - -
- - - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
-
+
-
-
-
-
- - -
- - - + + + + + - - -
-
- + + + + Override + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ REQUEST +

+
+
+ + String + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + request + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- request -
-
-
-
- + - -
- + request +
+ +
+ + +
+ + + + - -
- - -
- - - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
-
+
-
-
-
-
- - -
- - - + + + + + - - -
-
- + + + + Override + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ RESPONSE +

+
+
+ + String + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + response + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- response -
-
-
-
- + - -
- + response +
+ +
+ + +
+ + + + - -
- - -
- - - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
-
+
-
-
-
-
- - -
- - - + + + + + - - -
-
- + + + + Override + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ TAGS +

+
+
+ + String + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + tags + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- tags -
-
-
-
- + - -
- + tags +
+ +
+ + +
+ + + + - -
- - -
- - - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
-
+
-
-
-
-
- - -
- - - + + + + + - - -
-
- + + + + + + + + Default Timestamp + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ TIMESTAMP +

+
+
+ + Timestamp + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + timestamp + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- timestamp -
-
-
-
- - - - + - -
- -
- - - - - - - Default Timestamp - - - - - -
-
-
-
+ timestamp +
+ + - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + +
+ + + + + + + + Default Timestamp + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
-
+
-
-
-
-
- - -
- - - + + + + + - - -
-
- + + + + Override + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ URL +

+
+
+ + String + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + url + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- url -
-
-
-
- + - -
- + url +
+ +
+ + +
+ + + + - -
- - -
- - - - -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
-
+
-
-
-
-
- - -
- - - + + + + + - - -
-
- + + + + + + + Override + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > + + + +

+ UTC_TIME +

+
+
+ + Timestamp + +
+ +
+
+ + + + + + + } + fieldIcon={ + + } + fieldName={ + + + utc_time + + + } + isActive={false} + onClick={[Function]} + size="s" >
- -
-
-
- -
- -
- utc_time -
-
-
-
- - - - + - -
- + utc_time +
+ +
+ + +
+ + + + + + + - -
- - -
- -
- - - - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} + viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + + + + + + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + onBlur={[Function]} + onFocus={[Function]} + ownFocus={true} + panelClassName="explorerSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
-
- - - -
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + +
- - - -
- - -
+ + + + - - - - - - - -
-
+ viewBox="0 0 16 16" + width={16} + xmlns="http://www.w3.org/2000/svg" + /> + + + + +
+
+
-
+
-
-
-
-
- - -
-
- -
-
- - - -
-
- -
-
- + + + + + +
+ +
+
+ + + +
+
+ +
+
+ +
+ diff --git a/public/components/event_analytics/explorer/sidebar/__tests__/field.test.tsx b/public/components/event_analytics/explorer/sidebar/__tests__/field.test.tsx index caa4622c8..472812664 100644 --- a/public/components/event_analytics/explorer/sidebar/__tests__/field.test.tsx +++ b/public/components/event_analytics/explorer/sidebar/__tests__/field.test.tsx @@ -9,11 +9,6 @@ import React from 'react'; import { waitFor } from '@testing-library/react'; import { Field } from '../field'; import { AGENT_FIELD } from '../../../../../../test/event_analytics_constants'; -import { applyMiddleware, createStore } from 'redux'; -import { rootReducer } from '../../../../../framework/redux/reducers'; -import thunk from 'redux-thunk'; -import { Provider } from 'react-redux'; -import { DEFAULT_DATA_SOURCE_TYPE } from '../../../../../../common/constants/data_sources'; describe('Field component', () => { configure({ adapter: new Adapter() }); @@ -22,29 +17,25 @@ describe('Field component', () => { const onToggleField = jest.fn(); const handleOverrideTimestamp = jest.fn(); const selectedTimestamp = 'timestamp'; - const store = createStore(rootReducer, applyMiddleware(thunk)); - + const wrapper = mount( - - - + ); - + wrapper.update(); await waitFor(() => { expect(wrapper).toMatchSnapshot(); }); }); -}); +}); \ No newline at end of file diff --git a/public/components/event_analytics/explorer/sidebar/__tests__/sidebar.test.tsx b/public/components/event_analytics/explorer/sidebar/__tests__/sidebar.test.tsx index de25918df..c6d2e6bfd 100644 --- a/public/components/event_analytics/explorer/sidebar/__tests__/sidebar.test.tsx +++ b/public/components/event_analytics/explorer/sidebar/__tests__/sidebar.test.tsx @@ -22,10 +22,6 @@ import { JSON_DATA, JSON_DATA_ALL, } from '../../../../../../test/event_analytics_constants'; -import { applyMiddleware, createStore } from 'redux'; -import { rootReducer } from '../../../../../framework/redux/reducers'; -import thunk from 'redux-thunk'; -import { DEFAULT_DATA_SOURCE_TYPE } from '../../../../../../common/constants/data_sources'; jest.mock('react-redux', () => ({ ...jest.requireActual('react-redux'), @@ -86,10 +82,9 @@ describe('Siderbar component', () => { jsonData: JSON_DATA, jsonDataAll: JSON_DATA_ALL, }; - const astore = createStore(rootReducer, applyMiddleware(thunk)); const wrapper = mount( - + { isFieldToggleButtonDisabled={false} isOverridingTimestamp={false} storedExplorerFields={explorerFields} - tabId={DEFAULT_DATA_SOURCE_TYPE} /> ); diff --git a/public/components/event_analytics/explorer/sidebar/field.tsx b/public/components/event_analytics/explorer/sidebar/field.tsx index edb4d5baf..b55f5ff2c 100644 --- a/public/components/event_analytics/explorer/sidebar/field.tsx +++ b/public/components/event_analytics/explorer/sidebar/field.tsx @@ -16,15 +16,11 @@ import { EuiFlexItem, EuiTitle, EuiText, - EuiBadge, } from '@elastic/eui'; -import { useSelector } from 'react-redux'; import { FieldButton } from '../../../common/field_button'; import { FieldIcon } from '../../../common/field_icon'; import { IField } from '../../../../../common/types/explorer'; import { FieldInsights } from './field_insights'; -import { DEFAULT_DATA_SOURCE_TYPE } from '../../../../../common/constants/data_sources'; -import { selectSearchMetaData } from '../../../event_analytics/redux/slices/search_meta_data_slice'; interface IFieldProps { query: string; @@ -40,7 +36,6 @@ interface IFieldProps { showTimestampOverrideButton: boolean; isFieldToggleButtonDisabled: boolean; onToggleField: (field: IField) => void; - tabId: string; } export const Field = (props: IFieldProps) => { @@ -57,14 +52,9 @@ export const Field = (props: IFieldProps) => { isFieldToggleButtonDisabled = false, showTimestampOverrideButton = true, onToggleField, - tabId, } = props; const [isFieldDetailsOpen, setIsFieldDetailsOpen] = useState(false); - const explorerSearchMeta = useSelector(selectSearchMetaData)[tabId] || {}; - const isDefaultDataSourceType = - explorerSearchMeta.datasources?.[0]?.type === DEFAULT_DATA_SOURCE_TYPE; - const appLogEvents = tabId.startsWith('application-analytics-tab'); const addLabelAria = i18n.translate('addButtonAriaLabel', { defaultMessage: 'Add {field} to table', @@ -83,93 +73,57 @@ export const Field = (props: IFieldProps) => { onToggleField(fields); }; - return ( - - - - - - {field.name} - - - <> - {isEqual(field.type, 'string') ? ( - isEqual(selectedPattern, field.name) ? ( - - {' '} - - - Default Pattern - - - - ) : isOverridingPattern ? ( - + const getFieldActionDOM = () => { + return ( + <> + + <> + {isEqual(field.type, 'string') ? ( + isEqual(selectedPattern, field.name) ? ( + + Default Pattern + + ) : isOverridingPattern ? ( - - ) : ( - + ) : ( handleOverridePattern(field)} data-test-subj="eventExplorer__overrideDefaultPattern" - className="dscSidebarField__actionButton" - isDisabled={!(isDefaultDataSourceType || appLogEvents)} > Override - - ) - ) : null} - - - - <> - {showTimestampOverrideButton && isEqual(field.type, 'timestamp') ? ( - isEqual(selectedTimestamp, field.name) ? ( - - - {' '} - - Default Timestamp - - - - ) : isOverridingTimestamp ? ( - + ) + ) : null} + + + + <> + {showTimestampOverrideButton && isEqual(field.type, 'timestamp') ? ( + isEqual(selectedTimestamp, field.name) ? ( + + Default Timestamp + + ) : isOverridingTimestamp ? ( - - ) : ( - + ) : ( handleOverrideTimestamp(field)} data-test-subj="eventExplorer__overrideDefaultTimestamp" - className="dscSidebarField__actionButton" - isDisabled={!(isDefaultDataSourceType || appLogEvents)} > Override - - ) - ) : null} - - - + ) + ) : null} + + { closePopover={() => setIsFieldDetailsOpen(false)} anchorPosition="rightUp" panelClassName="explorerSidebarItem__fieldPopoverPanel" - button={ - - } + button={} > @@ -201,8 +146,6 @@ export const Field = (props: IFieldProps) => { - - { isDisabled data-test-subj={`fieldToggle-${field.name}`} aria-label={selected ? removeLabelAria : addLabelAria} - className="dscSidebarField__actionButton" /> ) : ( { }} data-test-subj={`fieldToggle-${field.name}`} aria-label={selected ? removeLabelAria : addLabelAria} - className="dscSidebarField__actionButton" /> )} - - + + ); + }; + + return ( + } + fieldName={ + + {field.name} + + } + fieldAction={getFieldActionDOM()} + onClick={togglePopover} + /> ); }; diff --git a/public/components/event_analytics/explorer/sidebar/field_insights.tsx b/public/components/event_analytics/explorer/sidebar/field_insights.tsx index a8a60a58f..2b82bfa0e 100644 --- a/public/components/event_analytics/explorer/sidebar/field_insights.tsx +++ b/public/components/event_analytics/explorer/sidebar/field_insights.tsx @@ -3,11 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { useMemo, useState, useEffect } from 'react'; +import React, { useMemo, useState, useContext, useEffect } from 'react'; import { indexOf, last } from 'lodash'; import { EuiFlexGroup, EuiFlexItem, EuiLink, EuiBasicTable } from '@elastic/eui'; import { getIndexPatternFromRawQuery } from '../../../common/query_utils'; -import { coreRefs } from '../../../../framework/core_refs'; +import { TabContext } from '../../hooks/use_tab_context'; interface IInsightsReq { id: string; @@ -19,7 +19,7 @@ interface IInsightsReq { type IInsightsReqParams = Pick; export const FieldInsights = ({ field, query }: any) => { - const { pplService } = coreRefs; + const { pplService } = useContext(TabContext); const { rawQuery } = query; const index = getIndexPatternFromRawQuery(rawQuery); const generalReports = [ @@ -115,11 +115,11 @@ export const FieldInsights = ({ field, query }: any) => { .catch((error) => { console.error(error); }); - }, [query]); + }, []); const getInsights = async (insightParams: IInsightsReqParams) => { try { - return await pplService?.fetch(insightParams); + return await pplService.fetch(insightParams); } catch (error) { console.error(error); } diff --git a/public/components/event_analytics/explorer/sidebar/observability_sidebar.tsx b/public/components/event_analytics/explorer/sidebar/observability_sidebar.tsx deleted file mode 100644 index 89cb4e5e6..000000000 --- a/public/components/event_analytics/explorer/sidebar/observability_sidebar.tsx +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -import React, { useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import _, { isEmpty } from 'lodash'; -import { changeQuery, selectQueries } from '../../redux/slices/query_slice'; -import { selectQueryResult } from '../../redux/slices/query_result_slice'; -import { selectFields } from '../../redux/slices/field_slice'; -import { - RAW_QUERY, - SELECTED_PATTERN_FIELD, - SELECTED_TIMESTAMP, -} from '../../../../../common/constants/explorer'; -import { PPL_STATS_REGEX } from '../../../../../common/constants/shared'; -import { Sidebar } from './sidebar'; -import { useFetchPatterns } from '../../hooks'; -import { formatError } from '../../utils'; -import { IField } from '../../../../../common/types/explorer'; -import { selectCountDistribution } from '../../redux/slices/count_distribution_slice'; - -export const ObservabilitySideBar = ({ tabId, pplService, notifications }) => { - const dispatch = useDispatch(); - const query = useSelector(selectQueries)[tabId]; - const explorerData = useSelector(selectQueryResult)[tabId]; - const explorerFields = useSelector(selectFields)[tabId]; - const countDistribution = useSelector(selectCountDistribution)[tabId]; - const requestParams = { tabId }; - const { - isEventsLoading: isPatternLoading, - getPatterns, - setDefaultPatternsField, - } = useFetchPatterns({ - pplService, - requestParams, - }); - const [isOverridingPattern, setIsOverridingPattern] = useState(false); - const [isOverridingTimestamp, setIsOverridingTimestamp] = useState(false); - - const getErrorHandler = (title: string) => { - return (error: any) => { - const formattedError = formatError(error.name, error.message, error.body.message); - notifications.toasts.addError(formattedError, { - title, - }); - }; - }; - - const handleOverridePattern = async (pattern: IField) => { - setIsOverridingPattern(true); - await setDefaultPatternsField( - '', - pattern.name, - getErrorHandler('Error overriding default pattern') - ); - setIsOverridingPattern(false); - await getPatterns( - countDistribution.selectedInterval || 'y', - getErrorHandler('Error fetching patterns') - ); - }; - - const handleOverrideTimestamp = async (timestamp: IField) => { - setIsOverridingTimestamp(true); - await dispatch( - changeQuery({ - tabId, - query: { - [SELECTED_TIMESTAMP]: timestamp?.name || '', - }, - }) - ); - setIsOverridingTimestamp(false); - }; - - return ( - - ); -}; diff --git a/public/components/event_analytics/explorer/sidebar/sidebar.scss b/public/components/event_analytics/explorer/sidebar/sidebar.scss index b9eeb45ff..8f96c7764 100644 --- a/public/components/event_analytics/explorer/sidebar/sidebar.scss +++ b/public/components/event_analytics/explorer/sidebar/sidebar.scss @@ -3,22 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - .dscSidebarField { - &__actionButton { - opacity: 0; - transition: opacity $euiAnimSpeedFast; - - @include ouiBreakpoint("xs", "s", "m") { - opacity: 1; - } - } - - &:hover &__actionButton, - &:focus &__actionButton { - opacity: 1; - } -} - .explorerIndexPattern__container { display: flex; align-items: center; @@ -144,16 +128,4 @@ .sidebar_content{ white-space: nowrap; padding: 0.1px; -} - -// align with discover 2.0 sidebar styling - -.dscSideBarFieldListHeader { - padding-left: 8px; -} - -.deSidebar { - height: calc(100vh - 98px); - max-width: 462px; - min-width: 400px; } \ No newline at end of file diff --git a/public/components/event_analytics/explorer/sidebar/sidebar.tsx b/public/components/event_analytics/explorer/sidebar/sidebar.tsx index f489d3bb5..ea4d59782 100644 --- a/public/components/event_analytics/explorer/sidebar/sidebar.tsx +++ b/public/components/event_analytics/explorer/sidebar/sidebar.tsx @@ -4,20 +4,23 @@ */ import { + EuiAccordion, EuiDragDropContext, EuiDraggable, EuiDroppable, EuiFieldSearch, - EuiTitle, - EuiSplitPanel, + EuiHorizontalRule, EuiPanel, + EuiSpacer, + EuiTitle, } from '@elastic/eui'; -import { FormattedMessage, I18nProvider } from '@osd/i18n/react'; +import { I18nProvider } from '@osd/i18n/react'; import { isEmpty } from 'lodash'; -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useContext, useState } from 'react'; import { batch, useDispatch } from 'react-redux'; import { AVAILABLE_FIELDS, SELECTED_FIELDS } from '../../../../../common/constants/explorer'; import { ExplorerFields, IExplorerFields, IField } from '../../../../../common/types/explorer'; +import { TabContext } from '../../hooks/use_tab_context'; import { sortFields, updateFields } from '../../redux/slices/field_slice'; import { Field } from './field'; @@ -34,7 +37,6 @@ interface ISidebarProps { handleOverrideTimestamp: (timestamp: IField) => void; storedExplorerFields: IExplorerFields; setStoredExplorerFields: (explorer: IExplorerFields) => void; - tabId: string; } export const Sidebar = (props: ISidebarProps) => { @@ -49,24 +51,14 @@ export const Sidebar = (props: ISidebarProps) => { isFieldToggleButtonDisabled, handleOverridePattern, handleOverrideTimestamp, - tabId, + storedExplorerFields, + setStoredExplorerFields, } = props; const dispatch = useDispatch(); + const { tabId } = useContext(TabContext); const [showFields, setShowFields] = useState(false); const [searchTerm, setSearchTerm] = useState(''); - // method to return the type of a field from its name - const getFieldTypes = (newFieldName: string) => { - let fieldType: string = ''; - explorerFields.availableFields.map((field) => { - if (field.name === newFieldName) fieldType = field.type; - }); - explorerFields.selectedFields.map((field) => { - if (field.name === newFieldName) fieldType = field.type; - }); - return fieldType; - }; - /** * Toggle fields between selected and unselected sets * @param fieldState all fields in store @@ -108,88 +100,81 @@ export const Sidebar = (props: ISidebarProps) => { }); }; + const checkWithStoredFields = () => { + if ( + explorerFields.selectedFields.length === 0 && + storedExplorerFields.selectedFields.length !== 0 + ) { + return storedExplorerFields; + } + return explorerFields; + }; + const handleAddField = useCallback( (field: IField) => { - updateStoreFields( - toggleFields(explorerFields, field, AVAILABLE_FIELDS, SELECTED_FIELDS), - tabId, + const nextFields = toggleFields( + checkWithStoredFields(), + field, + AVAILABLE_FIELDS, SELECTED_FIELDS ); + updateStoreFields(nextFields, tabId, SELECTED_FIELDS); + setStoredExplorerFields(nextFields); }, [explorerFields, tabId] ); const handleRemoveField = useCallback( (field: IField) => { - updateStoreFields( - toggleFields(explorerFields, field, SELECTED_FIELDS, AVAILABLE_FIELDS), - tabId, + const nextFields = toggleFields( + checkWithStoredFields(), + field, + SELECTED_FIELDS, AVAILABLE_FIELDS ); + updateStoreFields(nextFields, tabId, AVAILABLE_FIELDS); + setStoredExplorerFields(nextFields); }, [explorerFields, tabId] ); - const onDragEnd = ({ - destination, - source, - draggableId, - }: { - destination: any; - source: any; - draggableId: string; - }) => { - // check if the destination and source are the same area - if (destination.droppableId !== source.droppableId) { - // if dropped into the selected fields: add, if dropped into available: remove - if (destination.droppableId === 'SELECTED FIELDS') { - handleAddField({ name: draggableId, type: getFieldTypes(draggableId) }); - } else if (destination.droppableId === 'AVAILABLE FIELDS') { - handleRemoveField({ name: draggableId, type: getFieldTypes(draggableId) }); - } - } + const onDragEnd = ({}) => { + console.log('source, destination'); }; return ( - - -
- { - setSearchTerm(e.target.value); - }} - placeholder="Search field names" - value={searchTerm} - data-test-subj="eventExplorer__sidebarSearch" - /> -
-
- +
+
+ { + setSearchTerm(e.target.value); + }} + placeholder="Search field names" + value={searchTerm} + data-test-subj="eventExplorer__sidebarSearch" + /> +
+ +
{((explorerData && !isEmpty(explorerData.jsonData) && !isEmpty(explorerFields)) || !isEmpty(explorerFields.availableFields)) && ( <> {explorerFields?.queriedFields && explorerFields.queriedFields?.length > 0 && ( - <> - -

- -

-
+ + Query fields + + } + paddingSize="xs" + > + { - - - + ); })} - + )} - -

- -

-
- + + Selected Fields + + } + paddingSize="xs" > - {explorerData && - !isEmpty(explorerData?.jsonData) && - explorerFields?.selectedFields && - explorerFields?.selectedFields.map((field, index) => { - return ( - - + + {explorerData && + !isEmpty(explorerData?.jsonData) && + storedExplorerFields?.selectedFields && + storedExplorerFields?.selectedFields.map((field, index) => { + return ( + { isFieldToggleButtonDisabled={isFieldToggleButtonDisabled} showTimestampOverrideButton={true} onToggleField={handleRemoveField} - tabId={tabId} /> - - - ); - })} - - -

- -

-
- + ); + })} + + + + + Available Fields + + } + paddingSize="xs" > - {explorerFields?.availableFields && - explorerFields?.availableFields - .filter((field) => searchTerm === '' || field.name.indexOf(searchTerm) !== -1) - .map((field, index) => { - return ( - - + + {storedExplorerFields?.availableFields && + storedExplorerFields?.availableFields + .filter( + (field) => searchTerm === '' || field.name.indexOf(searchTerm) !== -1 + ) + .map((field, index) => { + return ( + { selected={false} isFieldToggleButtonDisabled={isFieldToggleButtonDisabled} showTimestampOverrideButton={true} - tabId={tabId} /> - - - ); - })} - + + ); + })} + + )} - - +
+
); diff --git a/public/components/event_analytics/explorer/visualizations/config_panel/config_panel.scss b/public/components/event_analytics/explorer/visualizations/config_panel/config_panel.scss index 23028f83a..7025380fc 100644 --- a/public/components/event_analytics/explorer/visualizations/config_panel/config_panel.scss +++ b/public/components/event_analytics/explorer/visualizations/config_panel/config_panel.scss @@ -158,7 +158,6 @@ $vis-editor-sidebar-min-width: 350px; #vis__mainContent .vis__leftPanel { overflow-y: unset; // unset default setting - margin-right: 8px; } .panelItem_button { @@ -169,15 +168,6 @@ $vis-editor-sidebar-min-width: 350px; align-items: center; } -.panelItem_box { - color: #5A6875; - display: grid; - grid-gap: 4px; - padding: 8px 8px 8px 8px; - background-color: #D6D9DD; - border-radius: 4px; -} - .field_text { text-overflow: ellipsis; overflow: hidden; @@ -204,9 +194,4 @@ $vis-editor-sidebar-min-width: 350px; .panel_section, .cp__rightHeader { border-bottom: 1px solid $border-color-on-dark; } - - .panelItem_box { - color: #8D98A3; - background-color: #293847; - } } \ No newline at end of file diff --git a/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_fields.tsx b/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_fields.tsx index 669a314c8..4c7f666c5 100644 --- a/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_fields.tsx +++ b/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_fields.tsx @@ -12,8 +12,6 @@ import { EuiText, EuiTitle, EuiToolTip, - EuiFormRow, - EuiFormLabel, } from '@elastic/eui'; import { isArray, isEmpty, lowerCase } from 'lodash'; import { @@ -62,7 +60,7 @@ export const DataConfigPanelFields = ({ const { time_field: timeField, unit, interval } = dimensionSpan; - const tooltipIcon = ; + const tooltipIcon = ; const crossIcon = (index: number, configName: string) => ( - <> -
- {sectionName} - {infoToolTip(tooltipIcon, DATA_CONFIG_HINTS_INFO[`${sectionName}`])} -
- -
- {sectionName === GROUPBY && dimensionSpan && !isEmpty(timeField) && ( +
+
+ +

{sectionName}

+
+ {infoToolTip(tooltipIcon, DATA_CONFIG_HINTS_INFO[`${sectionName}`])} +
+ + {sectionName === GROUPBY && dimensionSpan && !isEmpty(timeField) && ( + + + handleServiceEdit(list.length - 1, GROUPBY, true)} + data-test-subj="viz-config-add-btn" + > + {`${SPAN}(${timeField[0]?.name}, ${interval} ${unit[0]?.value})`} + + + {crossIcon(-1, SPAN)} + + )} + + {isArray(list) && + list.map((obj: ConfigListEntry, index: number) => ( + handleServiceEdit(list.length - 1, GROUPBY, true)} + onClick={() => handleServiceEdit(index, sectionName, false)} data-test-subj="viz-config-add-btn" > - {`${SPAN}(${timeField[0]?.name}, ${interval} ${unit[0]?.value})`} + {removeBacktick( + obj[CUSTOM_LABEL] || `${isAggregation ? obj.aggregation : ''} ${obj.label}` + )} - {crossIcon(-1, SPAN)} - - )} - {isArray(list) && - list.map((obj: ConfigListEntry, index: number) => ( - - - - handleServiceEdit(index, sectionName, false)} - data-test-subj="viz-config-add-btn" - > - {removeBacktick( - obj[CUSTOM_LABEL] || `${isAggregation ? obj.aggregation : ''} ${obj.label}` - )} - - - {isAggregation - ? infoToolTip( - crossIcon(index, sectionName), - DATA_CONFIG_HINTS_INFO[AGGREGATIONS] - ) - : crossIcon(index, sectionName)} - - - ))} - {!hideClickToAddButton(sectionName) && ( - - {addButtonText} - handleServiceAdd(sectionName)} - data-test-subj="viz-config-add-btn" - /> + {isAggregation + ? infoToolTip(crossIcon(index, sectionName), DATA_CONFIG_HINTS_INFO[AGGREGATIONS]) + : crossIcon(index, sectionName)} - )} -
- - + + + ))} + {!hideClickToAddButton(sectionName) && ( + + {addButtonText} + handleServiceAdd(sectionName)} + data-test-subj="viz-config-add-btn" + /> + + )} + +
); }; diff --git a/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_configurations_panel.scss b/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_configurations_panel.scss index 6ca8a2e84..cac373f90 100644 --- a/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_configurations_panel.scss +++ b/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_configurations_panel.scss @@ -39,50 +39,4 @@ &.showSecondary > .wizConfig__section { transform: translateX(-100%); } -} - -.vbConfig { - @include euiYScrollWithShadows; - - background: $euiColorLightestShade; - border-left: $euiBorderThin; - position: relative; - overflow-x: hidden; - - &__section { - width: 100%; - transition: transform $euiAnimSpeedNormal 0s $euiAnimSlightResistance; - } - - &__title { - padding: $euiSizeS; - padding-bottom: 0; - - &.showDivider { - border-bottom: 1px solid $euiColorLightShade; - } - } - - &__content { - padding: $euiSizeS; - } - - &__aggEditor { - padding: 0 $euiSizeM; - } - - &--secondary { - position: absolute; - top: 0; - left: 0; - padding: $euiSizeS; - - .visEditorAggParam--half { - margin: $euiSize 0; - } - } - - &.showSecondary > .vbConfig__section { - transform: translateX(-100%); - } } \ No newline at end of file diff --git a/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_configurations_panel.tsx b/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_configurations_panel.tsx index d55fedc85..e5374811e 100644 --- a/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_configurations_panel.tsx +++ b/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_configurations_panel.tsx @@ -16,9 +16,6 @@ import { EuiSpacer, EuiTitle, htmlIdGenerator, - EuiForm, - EuiFlexGroup, - EuiHorizontalRule, } from '@elastic/eui'; import { filter, isEmpty, isEqual } from 'lodash'; import { @@ -343,7 +340,7 @@ export const DataConfigPanelItem = ({ const selectedObj = isTimeStampSelected ? configList[SPAN] : configList[name][index]; const isAggregations = name === AGGREGATIONS; return ( -
+ <>
-
+ ); }; @@ -538,59 +535,49 @@ export const DataConfigPanelItem = ({ return isAddConfigClicked ? ( getCommonUI(selectedConfigItem.name) ) : ( - -
-
- - - -

Configuration

-
-
-
-
- {visualizations.vis.name !== VIS_CHART_TYPES.Histogram ? ( -
- - {DataConfigPanelFields(getRenderFieldsObj(AGGREGATIONS))} - - {DataConfigPanelFields(getRenderFieldsObj(GROUPBY))} - - {(visualizations.vis.name === VIS_CHART_TYPES.Bar || - visualizations.vis.name === VIS_CHART_TYPES.HorizontalBar || - visualizations.vis.name === VIS_CHART_TYPES.Line) && ( - <>{DataConfigPanelFields(getRenderFieldsObj(BREAKDOWNS))} - )} - -
- ) : ( - <> - -

Bucket Size

-
- {getNumberField('bucketSize')} + <> + +

Configuration

+
+ + {visualizations.vis.name !== VIS_CHART_TYPES.Histogram ? ( + <> + {DataConfigPanelFields(getRenderFieldsObj(AGGREGATIONS))} + + {DataConfigPanelFields(getRenderFieldsObj(GROUPBY))} + + {(visualizations.vis.name === VIS_CHART_TYPES.Bar || + visualizations.vis.name === VIS_CHART_TYPES.HorizontalBar || + visualizations.vis.name === VIS_CHART_TYPES.Line) && ( + <>{DataConfigPanelFields(getRenderFieldsObj(BREAKDOWNS))} + )} + + ) : ( + <> + +

Bucket Size

+
+ {getNumberField('bucketSize')} - - -

Bucket Offset

-
- {getNumberField('bucketOffset')} - - )} -
- - updateChart()} - size="s" - isDisabled={isEmpty(configList[AGGREGATIONS])} - > - Update chart - - -
-
-
+ + +

Bucket Offset

+
+ {getNumberField('bucketOffset')} + + )} + + + updateChart()} + size="s" + isDisabled={isEmpty(configList[AGGREGATIONS])} + > + Update chart + + + ); }; diff --git a/public/components/event_analytics/explorer/visualizations/direct_query_vis.tsx b/public/components/event_analytics/explorer/visualizations/direct_query_vis.tsx index a1268c62d..73d55f0a5 100644 --- a/public/components/event_analytics/explorer/visualizations/direct_query_vis.tsx +++ b/public/components/event_analytics/explorer/visualizations/direct_query_vis.tsx @@ -3,17 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { - EuiCallOut, - EuiFlexGroup, - EuiFlexItem, - EuiLink, - EuiPage, - EuiText, - EuiSpacer, -} from '@elastic/eui'; +import { EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiLink, EuiTitle } from '@elastic/eui'; import React from 'react'; -import { FormattedMessage, I18nProvider } from '@osd/i18n/react'; import { queryWorkbenchPluginID } from '../../../../../common/constants/shared'; import { coreRefs } from '../../../../framework/core_refs'; @@ -23,53 +14,31 @@ interface DirectQueryVisualizationProps { export const DirectQueryVisualization = ({ currentDataSource }: DirectQueryVisualizationProps) => { return ( - - - - - + + + +

+ + coreRefs?.application!.navigateToApp(queryWorkbenchPluginID, { + path: `#/${currentDataSource}`, + }) } - color="danger" - iconType="alert" > -

- - coreRefs?.application!.navigateToApp(queryWorkbenchPluginID, { - path: `#/${currentDataSource}`, - }) - } - > - - -

-
-
- - -

- -

- -
-
-
-
-
+ Index data to visualize + +

+ + + + +

Index data to visualize or select indexed data.

+
+

+ For external data only materialized views or covering indexes can be visualized. Ask your + administrator to create these indexes to visualize them. +

+
+ ); }; diff --git a/public/components/event_analytics/explorer/visualizations/index.tsx b/public/components/event_analytics/explorer/visualizations/index.tsx index 0b3a6bea5..f97db37f3 100644 --- a/public/components/event_analytics/explorer/visualizations/index.tsx +++ b/public/components/event_analytics/explorer/visualizations/index.tsx @@ -93,7 +93,16 @@ export const ExplorerVisualizations = ({ paddingSize="none" className="vis__leftPanel" > - {!isMarkDown && <>{renderDataConfigContainer()}} +
+ {!isMarkDown && ( +
+ {renderDataConfigContainer()} +
+ )} +
{ > Delete , + { + setIsActionsPopoverOpen(false); + history.push(`/explorer`); + }} + data-test-subj="eventHomeAction__explorer" + > + Event Explorer + , { @@ -284,19 +294,6 @@ const EventAnalyticsHome = (props: IHomeProps) => { - - { - setIsActionsPopoverOpen(false); - history.push(`/explorer`); - }} - data-test-subj="eventHomeAction__explorer" - fill - > - Event Explorer - - diff --git a/public/components/event_analytics/home/saved_objects_table.tsx b/public/components/event_analytics/home/saved_objects_table.tsx index 79c76c4ec..fbf761d90 100644 --- a/public/components/event_analytics/home/saved_objects_table.tsx +++ b/public/components/event_analytics/home/saved_objects_table.tsx @@ -116,7 +116,7 @@ export function SavedQueryTable({ type: 'field_value_selection', field: 'type', name: 'Type', - multiSelect: 'or', + multiSelect: false, options: FILTER_OPTIONS.map((i) => ({ value: i, name: i, diff --git a/public/components/event_analytics/index.tsx b/public/components/event_analytics/index.tsx index 585bfead9..815876599 100644 --- a/public/components/event_analytics/index.tsx +++ b/public/components/event_analytics/index.tsx @@ -31,23 +31,15 @@ export const EventAnalytics = ({ ...props }: EventAnalyticsProps) => { const [toasts, setToasts] = useState([]); - const [toastLifeTime, setToastLifeTime] = useState(6000); const eventAnalyticsBreadcrumb = { text: 'Logs', href: '#/', }; - const setToast = ( - title: string, - color = 'success', - text?: ReactChild, - side?: string, - toastLifeTimeMs?: number - ) => { + const setToast = (title: string, color = 'success', text?: ReactChild, side?: string) => { if (!text) text = ''; setToasts([...toasts, { id: new Date().toISOString(), title, text, color } as Toast]); - if (toastLifeTimeMs) setToastLifeTime(toastLifeTimeMs); }; return ( @@ -57,7 +49,7 @@ export const EventAnalytics = ({ dismissToast={(removedToast) => { setToasts(toasts.filter((toast) => toast.id !== removedToast.id)); }} - toastLifeTimeMs={toastLifeTime} + toastLifeTimeMs={6000} /> diff --git a/public/components/event_analytics/redux/slices/count_distribution_slice.ts b/public/components/event_analytics/redux/slices/count_distribution_slice.ts index b960c5064..59aa1e03f 100644 --- a/public/components/event_analytics/redux/slices/count_distribution_slice.ts +++ b/public/components/event_analytics/redux/slices/count_distribution_slice.ts @@ -17,7 +17,6 @@ export const countDistributionSlice = createSlice({ reducers: { render: (state, { payload }) => { state[payload.tabId] = { - ...state[payload.tabId], ...payload.data, }; }, diff --git a/public/components/event_analytics/redux/slices/query_slice.ts b/public/components/event_analytics/redux/slices/query_slice.ts index 38a9e41f8..b6e3b5f61 100644 --- a/public/components/event_analytics/redux/slices/query_slice.ts +++ b/public/components/event_analytics/redux/slices/query_slice.ts @@ -80,7 +80,7 @@ export const queriesSlice = createSlice({ extraReducers: (builder) => {}, }); -export const { changeQuery, changeDateRange, remove, init, reset } = queriesSlice.actions; +export const { changeQuery, changeDateRange, remove, init } = queriesSlice.actions; export const selectQueries = createSelector( (state) => state.queries, diff --git a/public/components/event_analytics/redux/slices/search_meta_data_slice.ts b/public/components/event_analytics/redux/slices/search_meta_data_slice.ts index 449515440..eee7083fa 100644 --- a/public/components/event_analytics/redux/slices/search_meta_data_slice.ts +++ b/public/components/event_analytics/redux/slices/search_meta_data_slice.ts @@ -3,63 +3,36 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { PayloadAction, createSelector, createSlice } from '@reduxjs/toolkit'; -import { REDUX_EXPL_SLICE_SEARCH_META_DATA } from '../../../../../common/constants/explorer'; -import { DirectQueryLoadingStatus, SelectedDataSource } from '../../../../../common/types/explorer'; +import { createSlice, createSelector } from '@reduxjs/toolkit'; import { initialTabId } from '../../../../framework/redux/store/shared_state'; - -const searchMetaInitialState = { - lang: 'PPL', - datasources: [], - queryId: '', - isPolling: false, -}; +import { REDUX_EXPL_SLICE_SEARCH_META_DATA } from '../../../../../common/constants/explorer'; const initialState = { [initialTabId]: { - ...searchMetaInitialState, - } as SearchMetaData, + lang: 'PPL', + datasources: [], + isPolling: false, + }, }; -interface SearchMetaData { - lang: string; - datasources: SelectedDataSource[]; - isPolling: boolean; - queryId: string; - status: DirectQueryLoadingStatus; -} - -interface SearchMetaDataState { - [key: string]: SearchMetaData; -} - -interface UpdatePayload { - tabId: string; - data: Partial; -} - export const searchMetaDataSlice = createSlice({ name: REDUX_EXPL_SLICE_SEARCH_META_DATA, initialState, reducers: { - update: (state, action: PayloadAction) => { - const { tabId, data } = action.payload; - state[tabId] = { - ...state[tabId], - ...data, + update: (state, { payload }) => { + state[payload.tabId] = { + ...state[payload.tabId], + ...payload.data, }; }, - reset: (state, action: PayloadAction<{ tabId: string }>) => { - const { tabId } = action.payload; - state[tabId] = { ...searchMetaInitialState }; + reset: (state, { payload }) => { + state[payload.tabId] = {}; }, - init: (state, action: PayloadAction<{ tabId: string }>) => { - const { tabId } = action.payload; - state[tabId] = { ...searchMetaInitialState }; + init: (state, { payload }) => { + state[payload.tabId] = {}; }, - remove: (state, action: PayloadAction<{ tabId: string }>) => { - const { tabId } = action.payload; - delete state[tabId]; + remove: (state, { payload }) => { + delete state[payload.tabId]; }, }, }); @@ -72,5 +45,3 @@ export const selectSearchMetaData = createSelector( ); export const searchMetaDataSliceReducer = searchMetaDataSlice.reducer; - -export type { SearchMetaData, SearchMetaDataState, UpdatePayload }; diff --git a/public/components/event_analytics/utils/__tests__/utils.test.tsx b/public/components/event_analytics/utils/__tests__/utils.test.tsx index 85a216b48..f6b5138d2 100644 --- a/public/components/event_analytics/utils/__tests__/utils.test.tsx +++ b/public/components/event_analytics/utils/__tests__/utils.test.tsx @@ -118,9 +118,7 @@ describe('Utils event analytics helper functions', () => { }); it('validates redoQuery function', () => { - const fetchEvents = jest.fn(); - const setData = jest.fn(); - + const getEvents = jest.fn(); redoQuery( '2023-01-01 00:00:00', '2023-09-28 23:19:10', @@ -137,14 +135,10 @@ describe('Utils event analytics helper functions', () => { { current: [0, 100], }, - fetchEvents, - setData + getEvents ); - const expectedFinalQuery = { - query: - "source=opensearch_dashboards_sample_data_logs | where timestamp >= '2023-01-01 00:00:00' and timestamp <= '2023-09-28 23:19:10' | where match(request,'filebeat') | sort + timestamp | head 100 from 0", - }; - // final query is the only thing being tested here - expect(fetchEvents).toBeCalledWith(expectedFinalQuery, 'jdbc', expect.anything()); + const expectedFinalQuery = + "source=opensearch_dashboards_sample_data_logs | where timestamp >= '2023-01-01 00:00:00' and timestamp <= '2023-09-28 23:19:10' | where match(request,'filebeat') | sort + timestamp | head 100 from 0"; + expect(getEvents).toBeCalledWith(expectedFinalQuery); }); }); diff --git a/public/components/event_analytics/utils/utils.tsx b/public/components/event_analytics/utils/utils.tsx index 996a656b6..d680860e1 100644 --- a/public/components/event_analytics/utils/utils.tsx +++ b/public/components/event_analytics/utils/utils.tsx @@ -413,8 +413,7 @@ export const redoQuery = ( timeStampField: string, sortingFields: MutableRefObject, pageFields: MutableRefObject, - fetchEvents: any, - setData: React.Dispatch> + getEvents: any ) => { let finalQuery = ''; @@ -437,8 +436,5 @@ export const redoQuery = ( finalQuery = finalQuery + ` | head ${pageFields.current[1]} from ${pageFields.current[0] * pageFields.current[1]}`; - - fetchEvents({ query: finalQuery }, 'jdbc', (res: any) => { - setData(res.jsonData); - }); + getEvents(finalQuery); }; diff --git a/public/components/hooks/index.ts b/public/components/hooks/index.ts index 3296182d4..d3c599c18 100644 --- a/public/components/hooks/index.ts +++ b/public/components/hooks/index.ts @@ -3,4 +3,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -export { usePolling, PollingConfigurations } from './use_polling'; +export { usePolling } from './use_polling'; diff --git a/public/components/hooks/use_direct_query_search.ts b/public/components/hooks/use_direct_query_search.ts new file mode 100644 index 000000000..a850c1690 --- /dev/null +++ b/public/components/hooks/use_direct_query_search.ts @@ -0,0 +1,4 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ diff --git a/public/components/hooks/use_polling.ts b/public/components/hooks/use_polling.ts index c1f79ada1..42fe5b9d3 100644 --- a/public/components/hooks/use_polling.ts +++ b/public/components/hooks/use_polling.ts @@ -7,65 +7,6 @@ import { useState, useRef } from 'react'; type FetchFunction = (params?: P) => Promise; -export interface PollingConfigurations { - tabId: string; -} - -export class UsePolling { - public data: T | null = null; - public error: Error | null = null; - public loading: boolean = true; - private shouldPoll: boolean = false; - private intervalRef?: NodeJS.Timeout; - - constructor( - private fetchFunction: FetchFunction, - private interval: number = 5000, - private onPollingSuccess?: (data: T, configurations: PollingConfigurations) => boolean, - private onPollingError?: (error: Error) => boolean, - private configurations?: PollingConfigurations - ) {} - - async fetchData(params?: P) { - this.loading = true; - try { - const result = await this.fetchFunction(params); - this.data = result; - this.loading = false; - - if (this.onPollingSuccess && this.onPollingSuccess(result, this.configurations!)) { - this.stopPolling(); - } - } catch (err) { - this.error = err as Error; - this.loading = false; - - if (this.onPollingError && this.onPollingError(this.error)) { - this.stopPolling(); - } - } - } - - startPolling(params?: P) { - this.shouldPoll = true; - if (!this.intervalRef) { - this.intervalRef = setInterval(() => { - if (this.shouldPoll) { - this.fetchData(params); - } - }, this.interval); - } - } - - stopPolling() { - this.shouldPoll = false; - if (this.intervalRef) { - clearInterval(this.intervalRef); - this.intervalRef = undefined; - } - } -} - interface UsePollingReturn { data: T | null; loading: boolean; @@ -76,10 +17,7 @@ interface UsePollingReturn { export function usePolling( fetchFunction: FetchFunction, - interval: number = 5000, - onPollingSuccess?: (data: T, configurations: PollingConfigurations) => boolean, - onPollingError?: (error: Error) => boolean, - configurations?: PollingConfigurations + interval: number = 5000 ): UsePollingReturn { const [data, setData] = useState(null); const [error, setError] = useState(null); @@ -107,18 +45,8 @@ export function usePolling( try { const result = await fetchFunction(params); setData(result); - - // Check the success condition and stop polling if it's met - if (onPollingSuccess && onPollingSuccess(result, configurations)) { - stopPolling(); - } - } catch (err: unknown) { - setError(err as Error); - - // Check the error condition and stop polling if it's met - if (onPollingError && onPollingError(err as Error)) { - stopPolling(); - } + } catch (err) { + setError(err); } finally { setLoading(false); } diff --git a/public/components/integrations/components/__tests__/__snapshots__/setup_integration.test.tsx.snap b/public/components/integrations/components/__tests__/__snapshots__/setup_integration.test.tsx.snap index 3688bcb34..2aa23faf3 100644 --- a/public/components/integrations/components/__tests__/__snapshots__/setup_integration.test.tsx.snap +++ b/public/components/integrations/components/__tests__/__snapshots__/setup_integration.test.tsx.snap @@ -31,7 +31,6 @@ exports[`Integration Setup Page Renders integration setup page as expected 1`] = Object { "connectionDataSource": "", "connectionLocation": "", - "connectionTableName": "sample", "connectionType": "index", "displayName": "sample Integration", } @@ -43,11 +42,6 @@ exports[`Integration Setup Page Renders integration setup page as expected 1`] = "type": "", } } - setupCallout={ - Object { - "show": false, - } - } updateConfig={[Function]} > @@ -66,11 +60,6 @@ exports[`Integration Setup Page Renders integration setup page as expected 1`] = className="euiSpacer euiSpacer--l" />
- -
-
@@ -108,15 +91,12 @@ exports[`Integration Setup Page Renders integration setup page as expected 1`] = className="euiFormRow__labelWrapper" >