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

[ES|QL] Bypass no data views screen #174316

Merged
merged 42 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8dec605
[No Data Prompt] ES|QL direct link
clintandrewhall Jan 5, 2024
b75c9ee
Convert handler to hook; simplify services; set appropriate index
clintandrewhall Jan 5, 2024
b590f50
Merge branch 'main' into shared_ux/prompt_esql
clintandrewhall Jan 9, 2024
e8204f0
Fix query logic
clintandrewhall Jan 9, 2024
8ff3b72
Address feedback
clintandrewhall Jan 9, 2024
2a9edec
Fix locator
stratoula Jan 11, 2024
d2d4930
Merge branch 'main' into shared_ux/prompt_esql
rshen91 Jan 16, 2024
43223f3
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jan 16, 2024
8728346
Merge branch 'main' into shared_ux/prompt_esql
rshen91 Jan 22, 2024
7a41b25
attempt to fix
rshen91 Jan 22, 2024
8275681
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jan 22, 2024
7d6b599
Merge branch 'main' of github.com:elastic/kibana into shared_ux/promp…
Dosant Jan 30, 2024
a84242c
change link styling
Dosant Jan 30, 2024
3afb946
fix navigation when in Discover
Dosant Jan 31, 2024
7615e8b
esql -> ESQL
Dosant Jan 31, 2024
3c0f90c
allow creating esql panels without default data view
Dosant Jan 31, 2024
581e5ba
allow to launch dashboard without a default data view
Dosant Jan 31, 2024
8f60f8b
fix button size
Dosant Jan 31, 2024
fe0cfc0
adjust dashboard no date state to allow for incoming es|ql chart with…
Dosant Jan 31, 2024
ea7af9f
Merge branch 'main' of github.com:elastic/kibana into shared_ux/promp…
Dosant Jan 31, 2024
214ea43
clean up
Dosant Jan 31, 2024
4274c32
wip fix deps
Dosant Jan 31, 2024
af8be65
fixes
Dosant Jan 31, 2024
648c2db
Merge branch 'main' of github.com:elastic/kibana into shared_ux/promp…
Dosant Jan 31, 2024
a0c3b5f
fix
Dosant Jan 31, 2024
66e9531
move finding first index for esql to utils
Dosant Jan 31, 2024
4080e2a
fix
Dosant Feb 1, 2024
f2a649c
Merge branch 'main' of github.com:elastic/kibana into shared_ux/promp…
Dosant Feb 1, 2024
a5e8010
fix
Dosant Feb 1, 2024
c2ab32a
Merge branch 'main' into shared_ux/prompt_esql
stratoula Feb 2, 2024
2a52aea
Merge branch 'main' of github.com:elastic/kibana into shared_ux/promp…
Dosant Feb 2, 2024
af27b8e
fix merge
Dosant Feb 2, 2024
ef4d45f
don’t show “try es|ql” on data view managament page
Dosant Feb 2, 2024
379bc71
Merge branch 'shared_ux/prompt_esql' of github.com:clintandrewhall/ki…
Dosant Feb 2, 2024
57c363b
don’t show “try es|ql” on data view managament page
Dosant Feb 2, 2024
45117b8
Merge branch 'main' of github.com:elastic/kibana into shared_ux/promp…
Dosant Feb 2, 2024
672e8c9
remove unwanted change
Dosant Feb 2, 2024
790c3c4
add ftr
Dosant Feb 2, 2024
5dd1f76
Merge branch 'main' of github.com:elastic/kibana into shared_ux/promp…
Dosant Feb 5, 2024
641acdc
add esql doc link
Dosant Feb 5, 2024
757d820
fix link
Dosant Feb 5, 2024
60df991
fix dashboard esql link
Dosant Feb 5, 2024
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
2 changes: 2 additions & 0 deletions packages/deeplinks/analytics/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ export const DISCOVER_APP_ID = 'discover';
export const DASHBOARD_APP_ID = 'dashboards';

export const VISUALIZE_APP_ID = 'visualize';

export const DISCOVER_ESQL_LOCATOR = 'DISCOVER_ESQL_LOCATOR';
9 changes: 8 additions & 1 deletion packages/deeplinks/analytics/deep_links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@
* Side Public License, v 1.
*/

import { DASHBOARD_APP_ID, DISCOVER_APP_ID, VISUALIZE_APP_ID } from './constants';
import {
DASHBOARD_APP_ID,
DISCOVER_APP_ID,
DISCOVER_ESQL_LOCATOR,
VISUALIZE_APP_ID,
} from './constants';

export type AppId = typeof DISCOVER_APP_ID | typeof DASHBOARD_APP_ID | typeof VISUALIZE_APP_ID;

export type DeepLinkId = AppId;

export type LocatorId = typeof DISCOVER_ESQL_LOCATOR;
7 changes: 6 additions & 1 deletion packages/deeplinks/analytics/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
* Side Public License, v 1.
*/

export { DASHBOARD_APP_ID, DISCOVER_APP_ID, VISUALIZE_APP_ID } from './constants';
export {
DASHBOARD_APP_ID,
DISCOVER_APP_ID,
VISUALIZE_APP_ID,
DISCOVER_ESQL_LOCATOR,
} from './constants';

export type { AppId, DeepLinkId } from './deep_links';
1 change: 1 addition & 0 deletions packages/kbn-es-query/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export {
migrateFilter,
fromCombinedFilter,
isOfQueryType,
isOfEsqlQueryType,
isOfAggregateQueryType,
getAggregateQueryMode,
getLanguageDisplayName,
Expand Down
9 changes: 9 additions & 0 deletions packages/kbn-es-query/src/es_query/es_aggregate_query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ export function isOfAggregateQueryType(
return Boolean(query && ('sql' in query || 'esql' in query));
}

/**
* True if the query is of type AggregateQuery and is of type esql, false otherwise.
*/
export function isOfEsqlQueryType(
query?: AggregateQuery | Query | { [key: string]: any }
): query is { esql: string } {
return Boolean(query && 'esql' in query && !('sql' in query));
}

// returns the language of the aggregate Query, sql, esql etc
export function getAggregateQueryMode(query: AggregateQuery): Language {
return Object.keys(query)[0] as Language;
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-es-query/src/es_query/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export { decorateQuery } from './decorate_query';
export {
isOfQueryType,
isOfAggregateQueryType,
isOfEsqlQueryType,
getAggregateQueryMode,
getLanguageDisplayName,
} from './es_aggregate_query';
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-esql-utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ export {
getIndexPatternFromESQLQuery,
getLimitFromESQLQuery,
removeDropCommandsFromESQLQuery,
getIndexForESQLQuery,
} from './src';
2 changes: 1 addition & 1 deletion packages/kbn-esql-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

export { getESQLAdHocDataview } from './utils/get_esql_adhoc_dataview';
export { getESQLAdHocDataview, getIndexForESQLQuery } from './utils/get_esql_adhoc_dataview';
export {
getIndexPatternFromSQLQuery,
getIndexPatternFromESQLQuery,
Expand Down
30 changes: 29 additions & 1 deletion packages/kbn-esql-utils/src/utils/get_esql_adhoc_dataview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ async function sha256(str: string) {
// This is a helper to create one. The id is constructed from the indexpattern.
// As there are no runtime fields or field formatters or default time fields
// the same adhoc dataview can be constructed/used. This comes with great advantages such
// as solving the problem descibed here https://github.com/elastic/kibana/issues/168131
// as solving the problem described here https://github.com/elastic/kibana/issues/168131
export async function getESQLAdHocDataview(
indexPattern: string,
dataViewsService: DataViewsPublicPluginStart
Expand All @@ -35,3 +35,31 @@ export async function getESQLAdHocDataview(
id: await sha256(`esql-${indexPattern}`),
});
}

/**
* This can be used to get an initial index for a default ES|QL query.
* Could be used during onboarding when data views to get a better index are not yet available.
* Can be used in combination with {@link getESQLAdHocDataview} to create a dataview for the index.
*/
export async function getIndexForESQLQuery(deps: {
dataViews: { getIndices: DataViewsPublicPluginStart['getIndices'] };
}): Promise<string | null> {
const indices = (
await deps.dataViews.getIndices({
showAllIndices: false,
pattern: '*',
isRollupIndex: () => false,
})
)
.filter((index) => !index.name.startsWith('.'))
.map((index) => index.name);

let indexName = indices[0];
if (indices.length > 0) {
if (indices.find((index) => index.startsWith('logs'))) {
indexName = 'logs*';
}
}

return indexName ?? null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { getHasApiKeys$ } from '../lib/get_has_api_keys';
export interface Props {
/** Handler for successfully creating a new data view. */
onDataViewCreated: (dataView: unknown) => void;
/** Handler for when try ES|QL is clicked and user has been navigated to try ES|QL in discover. */
onESQLNavigationComplete?: () => void;
/** if set to true allows creation of an ad-hoc dataview from data view editor */
allowAdHocDataView?: boolean;
/** if the kibana instance is customly branded */
Expand Down Expand Up @@ -116,6 +118,7 @@ const flavors: {
*/
export const AnalyticsNoDataPage: React.FC<AnalyticsNoDataPageProps> = ({
onDataViewCreated,
onESQLNavigationComplete,
allowAdHocDataView,
showPlainSpinner,
...services
Expand All @@ -131,7 +134,13 @@ export const AnalyticsNoDataPage: React.FC<AnalyticsNoDataPageProps> = ({

return (
<KibanaNoDataPage
{...{ noDataConfig, onDataViewCreated, allowAdHocDataView, showPlainSpinner }}
{...{
noDataConfig,
onDataViewCreated,
onESQLNavigationComplete,
allowAdHocDataView,
showPlainSpinner,
}}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { AnalyticsNoDataPage as Component } from './analytics_no_data_page.compo
*/
export const AnalyticsNoDataPage = ({
onDataViewCreated,
onESQLNavigationComplete,
allowAdHocDataView,
}: AnalyticsNoDataPageProps) => {
const { customBranding, ...services } = useServices();
Expand All @@ -29,6 +30,7 @@ export const AnalyticsNoDataPage = ({
showPlainSpinner={showPlainSpinner}
allowAdHocDataView={allowAdHocDataView}
onDataViewCreated={onDataViewCreated}
onESQLNavigationComplete={onESQLNavigationComplete}
/>
);
};
2 changes: 2 additions & 0 deletions packages/shared-ux/page/analytics_no_data/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,6 @@ export interface AnalyticsNoDataPageProps {
onDataViewCreated: (dataView: unknown) => void;
/** if set to true allows creation of an ad-hoc data view from data view editor */
allowAdHocDataView?: boolean;
/** Handler for when try ES|QL is clicked and user has been navigated to try ES|QL in discover. */
onESQLNavigationComplete?: () => void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { useServices } from './services';
*/
export const KibanaNoDataPage = ({
onDataViewCreated,
onESQLNavigationComplete,
noDataConfig,
allowAdHocDataView,
showPlainSpinner,
Expand Down Expand Up @@ -55,6 +56,7 @@ export const KibanaNoDataPage = ({
return (
<NoDataViewsPrompt
onDataViewCreated={onDataViewCreated}
onESQLNavigationComplete={onESQLNavigationComplete}
allowAdHocDataView={allowAdHocDataView}
/>
);
Expand Down
2 changes: 2 additions & 0 deletions packages/shared-ux/page/kibana_no_data/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,6 @@ export interface KibanaNoDataPageProps {
allowAdHocDataView?: boolean;
/** Set to true if the kibana is customly branded */
showPlainSpinner: boolean;
/** Handler for when try ES|QL is clicked and user has been navigated to try ES|QL in discover. */
onESQLNavigationComplete?: () => void;
}
1 change: 1 addition & 0 deletions packages/shared-ux/prompt/no_data_views/impl/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ export { NoDataViewsPrompt } from './src/no_data_views';
export { NoDataViewsPrompt as NoDataViewsPromptComponent } from './src/no_data_views.component';
export { NoDataViewsPromptKibanaProvider, NoDataViewsPromptProvider } from './src/services';
export { DataViewIllustration } from './src/data_view_illustration';
export { useOnTryESQL } from './src/hooks';
63 changes: 63 additions & 0 deletions packages/shared-ux/prompt/no_data_views/impl/src/actions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { EuiButton, EuiSpacer, EuiText } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import React from 'react';

interface NoDataButtonProps {
onClickCreate: (() => void) | undefined;
canCreateNewDataView: boolean;
onTryESQL?: () => void;
}

const createDataViewText = i18n.translate('sharedUXPackages.noDataViewsPrompt.addDataViewText', {
defaultMessage: 'Create data view',
});

export const NoDataButtonLink = ({
onClickCreate,
canCreateNewDataView,
onTryESQL,
}: NoDataButtonProps) => {
if (!onTryESQL && !canCreateNewDataView) {
return null;
}

return (
<>
{canCreateNewDataView && (
<EuiButton
onClick={onClickCreate}
iconType="plusInCircle"
fill={true}
data-test-subj="createDataViewButton"
>
{createDataViewText}
</EuiButton>
)}
{canCreateNewDataView && onTryESQL && <EuiSpacer />}
{onTryESQL && (
<EuiText size="xs" color={'subdued'}>
<FormattedMessage
id="sharedUXPackages.no_data_views.esqlMessage"
defaultMessage="Alternatively, you can query your data directly using ES|QL (technical preview)."
/>
<EuiSpacer size={'s'} />
<EuiButton color="success" onClick={onTryESQL} size="s" data-test-subj="tryESQLLink">
<FormattedMessage
id="sharedUXPackages.no_data_views.esqlButtonLabel"
defaultMessage="Try ES|QL"
/>
</EuiButton>
</EuiText>
)}
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

export { useOnTryESQL, type UseOnTryEsqlParams } from './use_on_try_esql';
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { useEffect, useState } from 'react';
import { DISCOVER_ESQL_LOCATOR } from '@kbn/deeplinks-analytics';

import { NavigateToAppFn, LocatorClient } from '@kbn/shared-ux-prompt-no-data-views-types';

export interface UseOnTryEsqlParams {
locatorClient?: LocatorClient;
navigateToApp: NavigateToAppFn;
}

export const useOnTryESQL = ({ locatorClient, navigateToApp }: UseOnTryEsqlParams) => {
const [onTryESQL, setOnTryEsql] = useState<(() => void) | undefined>();

useEffect(() => {
(async () => {
const location = await locatorClient?.get(DISCOVER_ESQL_LOCATOR)?.getLocation({});

if (!location) {
return;
}

const { app, path, state } = location;

setOnTryEsql(() => () => {
navigateToApp(app, { path, state });
});
})();
}, [locatorClient, navigateToApp]);

return onTryESQL;
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,13 @@
import React from 'react';
import { css } from '@emotion/react';

import { EuiButton, EuiEmptyPrompt, EuiPanel } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { EuiEmptyPrompt, EuiPanel } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { withSuspense } from '@kbn/shared-ux-utility';
import { NoDataViewsPromptComponentProps } from '@kbn/shared-ux-prompt-no-data-views-types';

import { DocumentationLink } from './documentation_link';

const createDataViewText = i18n.translate('sharedUXPackages.noDataViewsPrompt.addDataViewText', {
defaultMessage: 'Create data view',
});
import { NoDataButtonLink } from './actions';

// Using raw value because it is content dependent
const MAX_WIDTH = 830;
Expand All @@ -31,19 +27,9 @@ export const NoDataViewsPrompt = ({
onClickCreate,
canCreateNewDataView,
dataViewsDocLink,
onTryESQL,
emptyPromptColor = 'plain',
}: NoDataViewsPromptComponentProps) => {
const actions = canCreateNewDataView && (
<EuiButton
onClick={onClickCreate}
iconType="plusInCircle"
fill={true}
data-test-subj="createDataViewButton"
>
{createDataViewText}
</EuiButton>
);

const title = canCreateNewDataView ? (
<h2>
<FormattedMessage
Expand Down Expand Up @@ -94,6 +80,7 @@ export const NoDataViewsPrompt = ({
);

const icon = <Illustration />;
const actions = <NoDataButtonLink {...{ onClickCreate, canCreateNewDataView, onTryESQL }} />;

return (
<EuiEmptyPrompt
Expand All @@ -102,6 +89,13 @@ export const NoDataViewsPrompt = ({
css={css`
max-width: ${MAX_WIDTH}px !important; // Necessary to override EuiEmptyPrompt to fit content
flex-grow: 0;
// Necessary to override EuiEmptyPrompt to fit ES|QL prompt in one line
&.euiEmptyPrompt--horizontal .euiEmptyPrompt__icon {
min-width: 39%; // override from 40%
}
&.euiEmptyPrompt--horizontal .euiEmptyPrompt__content {
max-width: 38em; // override from 36em
}
`}
color={emptyPromptColor}
{...{ actions, icon, title, body, footer }}
Expand Down
Loading