Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 2.11] [Feature] Match discover look and feel #1179

Merged
merged 1 commit into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions common/constants/data_sources.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* 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',
}
1 change: 1 addition & 0 deletions common/constants/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ 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';
23 changes: 22 additions & 1 deletion common/types/explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ 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;
Expand Down Expand Up @@ -145,13 +146,23 @@ export interface IExplorerProps {
queryManager?: QueryManager;
}

export interface SavedQuery {
export interface SelectedDataSource {
label: string;
name: string;
value: string;
type: string;
ds?: DataSourceType;
}

export interface SavedQuery extends SavedObjectAttributes {
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 {
Expand All @@ -166,6 +177,8 @@ 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 {
Expand Down Expand Up @@ -406,3 +419,11 @@ export interface GridSortingColumn {
id: string;
direction: 'asc' | 'desc';
}

export enum DirectQueryLoadingStatus {
SUCCESS = 'SUCCESS',
FAILED = 'FAILED',
RUNNING = 'RUNNING',
SCHEDULED = 'SCHEDULED',
CANCELED = 'CANCELED',
}
16 changes: 14 additions & 2 deletions common/types/observability_saved_object_attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
*/

import { SavedObjectAttributes } from '../../../../src/core/types';
import { SavedVisualization } from './explorer';
import { SavedQuery, SavedVisualization } from './explorer';

export const VISUALIZATION_SAVED_OBJECT = 'observability-visualization';
export const OBSERVABILTY_SAVED_OBJECTS = [VISUALIZATION_SAVED_OBJECT] as const;
export const SEARCH_SAVED_OBJECT = 'observability-search';
export const OBSERVABILTY_SAVED_OBJECTS = [
VISUALIZATION_SAVED_OBJECT,
SEARCH_SAVED_OBJECT,
] as const;
export const SAVED_OBJECT_VERSION = 1;

export interface VisualizationSavedObjectAttributes extends SavedObjectAttributes {
Expand All @@ -17,3 +21,11 @@ export interface VisualizationSavedObjectAttributes extends SavedObjectAttribute
createdTimeMs: number;
savedVisualization: SavedVisualization;
}

export interface SearchSavedObjectAttributes extends SavedObjectAttributes {
title: string;
description: string;
version: number;
createdTimeMs: number;
savedQuery: SavedQuery;
}
1 change: 1 addition & 0 deletions common/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export {
buildRawQuery,
composeFinalQuery,
removeBacktick,
getSavingCommonParams,
} from '../../public/components/common/query_utils';

export * from './core_services';
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ export function Application(props: AppDetailProps) {
callback,
queryManager,
mode,
dataSourcePluggables,
} = props;
const [application, setApplication] = useState<ApplicationType>({
id: '',
Expand Down Expand Up @@ -371,6 +372,7 @@ export function Application(props: AppDetailProps) {
callbackInApp={callbackInApp}
queryManager={queryManager}
curSelectedTabId={selectedTabId}
dataSourcePluggables={dataSourcePluggables}
/>
);
};
Expand Down
2 changes: 2 additions & 0 deletions public/components/application_analytics/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export const Home = (props: HomeProps) => {
chrome,
notifications,
queryManager,
dataSourcePluggables,
} = props;
const [triggerSwitchToEvent, setTriggerSwitchToEvent] = useState(0);
const dispatch = useDispatch();
Expand Down Expand Up @@ -140,6 +141,7 @@ export const Home = (props: HomeProps) => {
setEndTime,
mode: 'data_prepper',
dataPrepperIndicesExist: indicesExist,
dataSourcePluggables,
};

const setToast = (title: string, color = 'success', text?: ReactChild) => {
Expand Down
2 changes: 1 addition & 1 deletion public/components/common/field_icon/field_icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const typeToEuiIconMap: Partial<Record<string, EuiTokenProps>> = {
export function FieldIcon({
type,
label,
size = 'l',
size = 's',
scripted,
className,
...rest
Expand Down
57 changes: 35 additions & 22 deletions public/components/common/query_utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@
import dateMath from '@elastic/datemath';
import { Moment } from 'moment-timezone';
import { isEmpty } from 'lodash';
import moment from 'moment';
import { SearchMetaData } from 'public/components/event_analytics/redux/slices/search_meta_data_slice';
import {
DATE_PICKER_FORMAT,
PPL_DEFAULT_PATTERN_REGEX_FILETER,
SELECTED_DATE_RANGE,
SELECTED_FIELDS,
SELECTED_TIMESTAMP,
} from '../../../../common/constants/explorer';
import {
PPL_DATE_FORMAT,
PPL_INDEX_INSERT_POINT_REGEX,
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
Expand Down Expand Up @@ -186,9 +189,6 @@ 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) {
Expand Down Expand Up @@ -245,24 +245,12 @@ export const buildPatternsQuery = (
return finalQuery;
};

export const buildQuery = (baseQuery: string, currQuery: string) => {
let fullQuery: string;
if (baseQuery) {
fullQuery = baseQuery;
if (currQuery) {
fullQuery += '| ' + currQuery;
}
} else {
fullQuery = currQuery;
}
return fullQuery;
};
export const buildQuery = (baseQuery: string, currQuery: string) => baseQuery + '| ' + currQuery;

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 buildRawQuery = (query: IQuery, appBaseQuery: string) => {
if (appBaseQuery && !query.rawQuery.includes(appBaseQuery))
return buildQuery(appBaseQuery, query.rawQuery);
return query.rawQuery;
};

export const composeFinalQuery = (
Expand Down Expand Up @@ -294,3 +282,28 @@ 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],
};
};
79 changes: 33 additions & 46 deletions public/components/common/search/search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,21 @@ import {
} from '@elastic/eui';
import { isEqual } from 'lodash';
import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { APP_ANALYTICS_TAB_ID_REGEX, RAW_QUERY } from '../../../../common/constants/explorer';
import { useDispatch } from 'react-redux';
import { APP_ANALYTICS_TAB_ID_REGEX } 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 {
selectSearchMetaData,
update as updateSearchMetaData,
} from '../../event_analytics/redux/slices/search_meta_data_slice';
import { 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;
Expand Down Expand Up @@ -97,14 +94,12 @@ 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('PPL');
const [jobId, setJobId] = useState('');
const [queryLang, setQueryLang] = useState(QUERY_LANGUAGE.PPL);
const sqlService = new SQLService(coreRefs.http);
const { application } = coreRefs;

Expand All @@ -119,7 +114,7 @@ export const Search = (props: any) => {
}, 5000);

const requestParams = { tabId };
const { getLiveTail, getEvents, getAvailableFields, dispatchOnGettingHis } = useFetchEvents({
const { dispatchOnGettingHis } = useFetchEvents({
pplService: new SQLService(coreRefs.http),
requestParams,
});
Expand Down Expand Up @@ -163,10 +158,9 @@ export const Search = (props: any) => {
);

const handleQueryLanguageChange = (lang: string) => {
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:''))`
);
if (lang === QUERY_LANGUAGE.DQL) {
application!.navigateToUrl('../app/data-explorer/discover');
return;
}
dispatch(
updateSearchMetaData({
Expand All @@ -187,10 +181,16 @@ export const Search = (props: any) => {
};

const languagePopOverItems = [
<EuiContextMenuItem key="PPL" onClick={() => handleQueryLanguageChange('PPL')}>
<EuiContextMenuItem
key={QUERY_LANGUAGE.PPL}
onClick={() => handleQueryLanguageChange(QUERY_LANGUAGE.PPL)}
>
PPL
</EuiContextMenuItem>,
<EuiContextMenuItem key="DQL" onClick={() => handleQueryLanguageChange('DQL')}>
<EuiContextMenuItem
key={QUERY_LANGUAGE.DQL}
onClick={() => handleQueryLanguageChange(QUERY_LANGUAGE.DQL)}
>
DQL
</EuiContextMenuItem>,
];
Expand All @@ -215,24 +215,9 @@ 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 (
<div className="globalQueryBar">
<EuiFlexGroup gutterSize="s" justifyContent="flexStart" alignItems="flexStart">
<EuiFlexGroup gutterSize="s" justifyContent="flexStart" alignItems="flexStart" wrap>
{appLogEvents && (
<EuiFlexItem style={{ minWidth: 110 }} grow={false}>
<EuiToolTip position="top" content={baseQuery}>
Expand All @@ -242,19 +227,21 @@ export const Search = (props: any) => {
</EuiToolTip>
</EuiFlexItem>
)}
<EuiFlexItem key="lang-selector" className="search-area lang-selector" grow={false}>
<EuiPopover
id="smallContextMenuExample"
button={languagePopOverButton}
isOpen={isLanguagePopoverOpen}
closePopover={closeLanguagePopover}
panelPaddingSize="none"
anchorPosition="downLeft"
>
<EuiContextMenuPanel size="s" items={languagePopOverItems} />
</EuiPopover>
</EuiFlexItem>
<EuiFlexItem key="search-bar" className="search-area" grow={5}>
{!appLogEvents && (
<EuiFlexItem key="lang-selector" className="search-area lang-selector" grow={false}>
<EuiPopover
id="smallContextMenuExample"
button={languagePopOverButton}
isOpen={isLanguagePopoverOpen}
closePopover={closeLanguagePopover}
panelPaddingSize="none"
anchorPosition="downLeft"
>
<EuiContextMenuPanel size="s" items={languagePopOverItems} />
</EuiPopover>
</EuiFlexItem>
)}
<EuiFlexItem key="search-bar" className="search-area" grow={5} style={{ minWidth: 400 }}>
<Autocomplete
key={'autocomplete-search-bar'}
query={query}
Expand Down
Loading
Loading