Skip to content

Commit

Permalink
Fix loading state UI for event analytics (#1902)
Browse files Browse the repository at this point in the history
Signed-off-by: Joshua Li <[email protected]>
  • Loading branch information
joshuali925 authored Jun 12, 2024
1 parent ed497fb commit 9864ef2
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 84 deletions.
34 changes: 19 additions & 15 deletions public/components/event_analytics/explorer/explorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ import {
PPL_NEWLINE_REGEX,
} from '../../../../common/constants/shared';
import { QueryManager } from '../../../../common/query_manager';
import { DatasourceType } from '../../../../common/types/data_connections';
import {
IExplorerProps,
IField,
Expand All @@ -88,6 +89,10 @@ import {
} from '../../../../common/utils';
import { coreRefs } from '../../../framework/core_refs';
import { initialTabId } from '../../../framework/redux/store/shared_state';
import {
getRenderCreateAccelerationFlyout,
getRenderLogExplorerTablesFlyout,
} from '../../../plugin';
import { PPLDataFetcher } from '../../../services/data_fetchers/ppl/ppl_data_fetcher';
import { getSavedObjectsClient } from '../../../services/saved_objects/saved_object_client/client_factory';
import { OSDSavedSearchClient } from '../../../services/saved_objects/saved_object_client/osd_saved_objects/saved_searches';
Expand All @@ -112,8 +117,8 @@ import {
import { getVizContainerProps } from '../../visualizations/charts/helpers';
import { TabContext, useFetchEvents, useFetchPatterns, useFetchVisualizations } from '../hooks';
import {
selectCountDistribution,
render as updateCountDistribution,
selectCountDistribution,
} from '../redux/slices/count_distribution_slice';
import { selectFields, updateFields } from '../redux/slices/field_slice';
import { selectQueryResult } from '../redux/slices/query_result_slice';
Expand All @@ -123,11 +128,12 @@ import { selectExplorerVisualization } from '../redux/slices/visualization_slice
import {
change as changeVisualizationConfig,
change as changeVizConfig,
selectVisualizationConfig,
change as updateVizConfig,
selectVisualizationConfig,
} from '../redux/slices/viualization_config_slice';
import { getDefaultVisConfig } from '../utils';
import { formatError, getContentTabTitle } from '../utils/utils';
import { AccelerateCallout } from './accelerate_callout';
import { DataSourceSelection } from './datasources/datasources_selection';
import { DirectQueryRunning } from './direct_query_running';
import { DataGrid } from './events_views/data_grid';
Expand All @@ -137,12 +143,6 @@ import { ObservabilitySideBar } from './sidebar/observability_sidebar';
import { getTimeRangeFromCountDistribution, HitsCounter, Timechart } from './timechart';
import { ExplorerVisualizations } from './visualizations';
import { DirectQueryVisualization } from './visualizations/direct_query_vis';
import {
getRenderCreateAccelerationFlyout,
getRenderLogExplorerTablesFlyout,
} from '../../../plugin';
import { AccelerateCallout } from './accelerate_callout';
import { DatasourceType } from '../../../../common/types/data_connections';

export const Explorer = ({
pplService,
Expand Down Expand Up @@ -180,14 +180,11 @@ export const Explorer = ({
pplService,
requestParams,
});
const {
isEventsLoading: _isPatternLoading,
getPatterns,
setDefaultPatternsField,
} = useFetchPatterns({
const { getPatterns, setDefaultPatternsField } = useFetchPatterns({
pplService,
requestParams,
});
const [eventsLoading, setEventsLoading] = useState(false);

const appLogEvents = tabId.startsWith('application-analytics-tab');
const query = useSelector(selectQueries)[tabId];
Expand Down Expand Up @@ -394,7 +391,7 @@ export const Explorer = ({
setSummaryStatus?: boolean
) => {
const curQuery: IQuery = queryRef.current!;
new PPLDataFetcher(
await new PPLDataFetcher(
{ ...curQuery },
{ batch, dispatch, changeQuery, changeVizConfig },
{
Expand Down Expand Up @@ -727,7 +724,11 @@ export const Explorer = ({
</EuiFlexItem>
</EuiFlexGroup>
) : (
<NoResults tabId={tabId} dataSourceConnectionType={dataSourceConnectionType} />
<NoResults
tabId={tabId}
dataSourceConnectionType={dataSourceConnectionType}
eventsLoading={eventsLoading}
/>
)}
</div>
);
Expand All @@ -742,6 +743,7 @@ export const Explorer = ({
isLiveTailOnRef.current,
isQueryRunning,
isS3Connection,
eventsLoading,
]);

const visualizationSettings = !isEmpty(userVizConfigs[curVisId])
Expand Down Expand Up @@ -824,6 +826,7 @@ export const Explorer = ({
};

const handleQuerySearch = async (availability?: boolean, setSummaryStatus?: boolean) => {
setEventsLoading(true);
// clear previous selected timestamp when index pattern changes
const searchedQuery = tempQueryRef.current;
if (
Expand All @@ -844,6 +847,7 @@ export const Explorer = ({
await updateQueryInStore(searchedQuery);
}
await fetchData(undefined, undefined, setSummaryStatus);
setEventsLoading(false);
};

const handleQueryChange = async (newQuery: string) => setTempQuery(newQuery);
Expand Down
118 changes: 61 additions & 57 deletions public/components/event_analytics/explorer/no_results.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,71 @@ import {
import { FormattedMessage } from '@osd/i18n/react';
import React from 'react';
import { useSelector } from 'react-redux';
import { DATA_SOURCE_TYPES, QUERY_LANGUAGE } from '../../../../common/constants/data_sources';
import { CachedDataSourceStatus, DatasourceType } from '../../../../common/types/data_connections';
import { CatalogCacheManager } from '../../../framework/catalog_cache/cache_manager';
import { coreRefs } from '../../../framework/core_refs';
import { getRenderLogExplorerTablesFlyout } from '../../../plugin';
import { selectQueryAssistantSummarization } from '../redux/slices/query_assistant_summarization_slice';
import { selectQueries } from '../redux/slices/query_slice';
import { selectSearchMetaData } from '../redux/slices/search_meta_data_slice';
import { DATA_SOURCE_TYPES, QUERY_LANGUAGE } from '../../../../common/constants/data_sources';
import { CatalogCacheManager } from '../../../framework/catalog_cache/cache_manager';
import { CachedDataSourceStatus, DatasourceType } from '../../../../common/types/data_connections';
import { getRenderLogExplorerTablesFlyout } from '../../../plugin';

export interface NoResultsProps {
tabId: string;
dataSourceConnectionType: DatasourceType;
eventsLoading: boolean;
}

export const NoResults = ({ tabId, dataSourceConnectionType }: NoResultsProps) => {
const CreatedCodeBlock = ({ code }: { code: string }) => {
return (
<EuiCodeBlock isCopyable={true} paddingSize="m" fontSize="s" language="sql">
{code}
</EuiCodeBlock>
);
};

const LoadingResults: React.FC = () => (
<EuiEmptyPrompt title={<EuiLoadingSpinner size="xl" />} body={<p>Loading results...</p>} />
);

const OpenSearchIndexNoResults = () => {
return (
<EuiFlexGroup justifyContent="center" direction="column">
<EuiFlexItem grow={false}>
<EuiCallOut
title={
<FormattedMessage
id="observability.noResults.noResultsMatchSearchCriteriaTitle"
defaultMessage="No results match your search criteria"
/>
}
color="warning"
iconType="help"
data-test-subj="observabilityNoResultsCallout"
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiSpacer size="s" />
<EuiText>
<h2 data-test-subj="obsNoResultsTimefilter">
<FormattedMessage
id="observability.noResults.expandYourTimeRangeTitle"
defaultMessage="Select a data source, expand your time range, or modify the query"
/>
</h2>
<p>
<FormattedMessage
id="observability.noResults.queryMayNotMatchTitle"
defaultMessage="After selection, check the time range, query filters, fields, and query"
/>
</p>
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
);
};

export const NoResults = ({ tabId, dataSourceConnectionType, eventsLoading }: NoResultsProps) => {
// get the queries isLoaded, if it exists AND is true = show no res
const queryInfo = useSelector(selectQueries)[tabId];
const summaryData = useSelector(selectQueryAssistantSummarization)[tabId];
Expand All @@ -46,14 +96,6 @@ export const NoResults = ({ tabId, dataSourceConnectionType }: NoResultsProps) =

const queryInputted = queryInfo?.rawQuery !== '';

const CreatedCodeBlock = ({ code }: any) => {
return (
<EuiCodeBlock isCopyable={true} paddingSize="m" fontSize="s" language="sql">
{code}
</EuiCodeBlock>
);
};

let arbitraryDatabaseName: string | undefined;
let arbitraryTableName: string | undefined;
let arbitraryRealQuery: string | undefined;
Expand All @@ -74,7 +116,7 @@ export const NoResults = ({ tabId, dataSourceConnectionType }: NoResultsProps) =

const renderTablesFlyout = getRenderLogExplorerTablesFlyout();

const S3Callouts = () => {
const renderS3Callouts = () => {
return (
<EuiFlexGroup justifyContent="center" direction="column">
{queryInputted && (
Expand Down Expand Up @@ -181,53 +223,13 @@ export const NoResults = ({ tabId, dataSourceConnectionType }: NoResultsProps) =
);
};

const OpenSearchIndexNoResults = () => {
return (
<EuiFlexGroup justifyContent="center" direction="column">
<EuiFlexItem grow={false}>
<EuiCallOut
title={
<FormattedMessage
id="observability.noResults.noResultsMatchSearchCriteriaTitle"
defaultMessage="No results match your search criteria"
/>
}
color="warning"
iconType="help"
data-test-subj="observabilityNoResultsCallout"
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiSpacer size="s" />
<EuiText>
<h2 data-test-subj="obsNoResultsTimefilter">
<FormattedMessage
id="observability.noResults.expandYourTimeRangeTitle"
defaultMessage="Select a data source, expand your time range, or modify the query"
/>
</h2>
<p>
<FormattedMessage
id="observability.noResults.queryMayNotMatchTitle"
defaultMessage="After selection, check the time range, query filters, fields, and query"
/>
</p>
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
);
};

return (
<EuiPage paddingSize="s">
{coreRefs.queryAssistEnabled ? (
<>
{/* check to see if the rawQuery is empty or not */}
{queryAssistLoading ? (
<EuiEmptyPrompt
title={<EuiLoadingSpinner size="xl" />}
body={<p>Loading results...</p>}
/>
{queryAssistLoading || eventsLoading ? (
<LoadingResults />
) : queryInfo?.rawQuery ? (
<EuiFlexGroup justifyContent="center" direction="column">
<EuiFlexItem grow={false}>
Expand Down Expand Up @@ -273,7 +275,9 @@ export const NoResults = ({ tabId, dataSourceConnectionType }: NoResultsProps) =
) : (
<>
{explorerSearchMeta?.datasources[0]?.type === DATA_SOURCE_TYPES.S3Glue ? (
<S3Callouts />
renderS3Callouts()
) : eventsLoading ? (
<LoadingResults />
) : (
<OpenSearchIndexNoResults />
)}
Expand Down
4 changes: 2 additions & 2 deletions public/components/event_analytics/hooks/use_fetch_events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,15 +193,15 @@ export const useFetchEvents = ({ pplService, requestParams }: IFetchEventsParams
);
};

const getEvents = (
const getEvents = async (
query: string = '',
errorHandler?: (error: any) => void,
setSummaryStatus?: boolean
) => {
if (isEmpty(query)) return;
const cur = queriesRef.current;
const searchQuery = isEmpty(query) ? cur![requestParams.tabId][FINAL_QUERY] : query;
fetchEvents(
await fetchEvents(
{ query: searchQuery },
'jdbc',
async (res: any) => {
Expand Down
27 changes: 17 additions & 10 deletions public/services/data_fetchers/ppl/ppl_data_fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@
*/

import isEmpty from 'lodash/isEmpty';
import { IDefaultTimestampState, IQuery } from '../../../../common/types/explorer';
import { IDataFetcher } from '../fetch_interface';
import { DataFetcherBase } from '../fetcher_base';
import {
buildRawQuery,
composeFinalQuery,
getIndexPatternFromRawQuery,
} from '../../../../common/utils';
import {
FILTERED_PATTERN,
PATTERNS_REGEX,
Expand All @@ -23,10 +15,18 @@ import {
TAB_CHART_ID,
} from '../../../../common/constants/explorer';
import { PPL_STATS_REGEX } from '../../../../common/constants/shared';
import { IDefaultTimestampState, IQuery } from '../../../../common/types/explorer';
import {
buildRawQuery,
composeFinalQuery,
getIndexPatternFromRawQuery,
} from '../../../../common/utils';
import {
composeFinalQueryWithoutTimestamp,
getDescribeQueryIndexFromRawQuery,
} from '../../../components/common/query_utils';
import { DataFetcherBase } from '../fetcher_base';
import { IDataFetcher } from '../fetch_interface';

export class PPLDataFetcher extends DataFetcherBase implements IDataFetcher {
protected queryIndex: string;
Expand Down Expand Up @@ -132,10 +132,15 @@ export class PPLDataFetcher extends DataFetcherBase implements IDataFetcher {
}

// get query data
let getDataPromise: Promise<void>;
if (isLiveTailOn) {
getLiveTail(finalQuery, getErrorHandler('Error fetching events'));
getDataPromise = getLiveTail(finalQuery, getErrorHandler('Error fetching events'));
} else {
getEvents(finalQuery, getErrorHandler('Error fetching events'), setSummaryStatus);
getDataPromise = getEvents(
finalQuery,
getErrorHandler('Error fetching events'),
setSummaryStatus
);
}
// still need all fields when query contains stats
if (finalQuery.match(PPL_STATS_REGEX)) getAvailableFields(`search source=${this.queryIndex}`);
Expand All @@ -157,6 +162,8 @@ export class PPLDataFetcher extends DataFetcherBase implements IDataFetcher {
})
);
}
// block search call until data retrieval and processing finishes
await getDataPromise;
}

async setLogPattern(query: IQuery, index: string, _finalQuery: string) {
Expand Down

0 comments on commit 9864ef2

Please sign in to comment.