Skip to content

Commit

Permalink
add onTryESQL prop to AnalyticsNoDataPage
Browse files Browse the repository at this point in the history
  • Loading branch information
tsullivan committed Oct 3, 2024
1 parent 9edb0cd commit db7cbae
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ 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 */
showPlainSpinner: boolean;
/** If the cluster has data, the user can be prompted to try ES|QL. This click handler customizes the action */
onTryESQL?: () => void;
/** Handler for when try ES|QL is clicked and user has been navigated to try ES|QL in discover. */
onESQLNavigationComplete?: () => void;
}

type AnalyticsNoDataPageProps = Props &
Expand Down Expand Up @@ -119,9 +121,10 @@ const flavors: {
*/
export const AnalyticsNoDataPage: React.FC<AnalyticsNoDataPageProps> = ({
onDataViewCreated,
onESQLNavigationComplete,
allowAdHocDataView,
showPlainSpinner,
onTryESQL,
onESQLNavigationComplete,
...services
}) => {
const { prependBasePath, kibanaGuideDocLink, getHttp: get, pageFlavor } = services;
Expand All @@ -138,8 +141,9 @@ export const AnalyticsNoDataPage: React.FC<AnalyticsNoDataPageProps> = ({
{...{
noDataConfig,
onDataViewCreated,
onESQLNavigationComplete,
allowAdHocDataView,
onTryESQL,
onESQLNavigationComplete,
showPlainSpinner,
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export default {

export const Analytics = (params: AnalyticsNoDataPageStorybookParams) => {
return (
<AnalyticsNoDataPageProvider {...mock.getServices(params)}>
<Component {...mock.getProps()} />
<AnalyticsNoDataPageProvider {...mock.getProps(params)} {...mock.getServices(params)}>
<Component {...mock.getProps(params)} />
</AnalyticsNoDataPageProvider>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
getAnalyticsNoDataPageServicesMock,
getAnalyticsNoDataPageServicesMockWithCustomBranding,
} from '@kbn/shared-ux-page-analytics-no-data-mocks';
import { NoDataViewsPrompt } from '@kbn/shared-ux-prompt-no-data-views';

import { AnalyticsNoDataPageProvider } from './services';
import { AnalyticsNoDataPage as Component } from './analytics_no_data_page.component';
Expand All @@ -29,28 +30,86 @@ describe('AnalyticsNoDataPage', () => {
jest.resetAllMocks();
});

it('renders correctly', async () => {
const component = mountWithIntl(
<AnalyticsNoDataPageProvider {...services}>
<AnalyticsNoDataPage onDataViewCreated={onDataViewCreated} allowAdHocDataView={true} />
</AnalyticsNoDataPageProvider>
);
describe('loading state', () => {
it('renders correctly', async () => {
const component = mountWithIntl(
<AnalyticsNoDataPageProvider {...services}>
<AnalyticsNoDataPage onDataViewCreated={onDataViewCreated} allowAdHocDataView={true} />
</AnalyticsNoDataPageProvider>
);

await act(() => new Promise(setImmediate));
await act(() => new Promise(setImmediate));

expect(component.find(Component).length).toBe(1);
expect(component.find(Component).props().onDataViewCreated).toBe(onDataViewCreated);
expect(component.find(Component).props().allowAdHocDataView).toBe(true);
expect(component.find(Component).length).toBe(1);
expect(component.find(Component).props().onDataViewCreated).toBe(onDataViewCreated);
expect(component.find(Component).props().allowAdHocDataView).toBe(true);
});

it('passes correct boolean value to showPlainSpinner', async () => {
const component = mountWithIntl(
<AnalyticsNoDataPageProvider {...servicesWithCustomBranding}>
<AnalyticsNoDataPage onDataViewCreated={onDataViewCreated} allowAdHocDataView={true} />
</AnalyticsNoDataPageProvider>
);

await act(async () => {
component.update();
});

expect(component.find(Component).length).toBe(1);
expect(component.find(Component).props().showPlainSpinner).toBe(true);
});
});

it('passes correct boolean value to showPlainSpinner', () => {
const component = mountWithIntl(
<AnalyticsNoDataPageProvider {...servicesWithCustomBranding}>
<AnalyticsNoDataPage onDataViewCreated={onDataViewCreated} allowAdHocDataView={true} />
</AnalyticsNoDataPageProvider>
);
describe('with ES data', () => {
jest.spyOn(services, 'hasESData').mockResolvedValue(true);
jest.spyOn(services, 'hasUserDataView').mockResolvedValue(false);

it('renders the prompt to create a data view', async () => {
const onTryESQL = jest.fn();

await act(async () => {
const component = mountWithIntl(
<AnalyticsNoDataPageProvider {...services}>
<AnalyticsNoDataPage
onDataViewCreated={onDataViewCreated}
allowAdHocDataView={true}
onTryESQL={onTryESQL}
/>
</AnalyticsNoDataPageProvider>
);

await new Promise(setImmediate);
component.update();

expect(component.find(Component).length).toBe(1);
expect(component.find(NoDataViewsPrompt).length).toBe(1);
});
});

it('renders the prompt to create a data view with a custom onTryESQL action', async () => {
const onTryESQL = jest.fn();

await act(async () => {
const component = mountWithIntl(
<AnalyticsNoDataPageProvider {...services}>
<AnalyticsNoDataPage
onDataViewCreated={onDataViewCreated}
allowAdHocDataView={true}
onTryESQL={onTryESQL}
/>
</AnalyticsNoDataPageProvider>
);

await new Promise(setImmediate);
component.update();

const tryESQLLink = component.find('button[data-test-subj="tryESQLLink"]');
expect(tryESQLLink.length).toBe(1);
tryESQLLink.simulate('click');

expect(component.find(Component).length).toBe(1);
expect(component.find(Component).props().showPlainSpinner).toBe(true);
expect(onTryESQL).toHaveBeenCalled();
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ import { AnalyticsNoDataPage as Component } from './analytics_no_data_page.compo
*/
export const AnalyticsNoDataPage = ({
onDataViewCreated,
onESQLNavigationComplete,
allowAdHocDataView,
onTryESQL,
onESQLNavigationComplete,
}: AnalyticsNoDataPageProps) => {
const { customBranding, ...services } = useServices();
const showPlainSpinner = useObservable(customBranding.hasCustomBranding$) ?? false;
Expand All @@ -33,6 +34,7 @@ export const AnalyticsNoDataPage = ({
allowAdHocDataView={allowAdHocDataView}
onDataViewCreated={onDataViewCreated}
onESQLNavigationComplete={onESQLNavigationComplete}
onTryESQL={onTryESQL}
/>
);
};
18 changes: 15 additions & 3 deletions packages/shared-ux/page/analytics_no_data/mocks/src/storybook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@ import type {
} from '@kbn/shared-ux-page-analytics-no-data-types';
import { of } from 'rxjs';

interface PropArguments {
useCustomOnTryESQL: boolean;
}

type ServiceArguments = Pick<AnalyticsNoDataPageServices, 'kibanaGuideDocLink' | 'customBranding'>;

export type Params = ArgumentParams<{}, ServiceArguments> & KibanaNoDataPageStorybookParams;
export type Params = ArgumentParams<PropArguments, ServiceArguments> &
KibanaNoDataPageStorybookParams;

const kibanaNoDataMock = new KibanaNoDataPageStorybookMock();

Expand All @@ -30,7 +35,13 @@ export class StorybookMock extends AbstractStorybookMock<
{},
ServiceArguments
> {
propArguments = {};
propArguments = {
// requires hasESData to be toggled to true
useCustomOnTryESQL: {
control: 'boolean',
defaultValue: false,
},
};
serviceArguments = {
kibanaGuideDocLink: {
control: 'text',
Expand Down Expand Up @@ -59,9 +70,10 @@ export class StorybookMock extends AbstractStorybookMock<
};
}

getProps() {
getProps(params: Params) {
return {
onDataViewCreated: action('onDataViewCreated'),
onTryESQL: params.useCustomOnTryESQL ? action('onTryESQL-from-props') : undefined,
};
}
}
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 @@ -70,6 +70,8 @@ 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;
/** If the cluster has data, the user can be prompted to try ES|QL. This click handler customizes the action */
onTryESQL?: () => void;
/** 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 @@ -20,9 +20,10 @@ import { useServices } from './services';
*/
export const KibanaNoDataPage = ({
onDataViewCreated,
onESQLNavigationComplete,
noDataConfig,
allowAdHocDataView,
onTryESQL,
onESQLNavigationComplete,
showPlainSpinner,
}: KibanaNoDataPageProps) => {
// These hooks are temporary, until this component is moved to a package.
Expand Down Expand Up @@ -58,8 +59,9 @@ export const KibanaNoDataPage = ({
return (
<NoDataViewsPrompt
onDataViewCreated={onDataViewCreated}
onESQLNavigationComplete={onESQLNavigationComplete}
allowAdHocDataView={allowAdHocDataView}
onTryESQL={onTryESQL}
onESQLNavigationComplete={onESQLNavigationComplete}
/>
);
}
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,6 +59,8 @@ export interface KibanaNoDataPageProps {
/** if set to true allows creation of an ad-hoc dataview from data view editor */
allowAdHocDataView?: boolean;
/** Set to true if the kibana is customly branded */
/** **/
onTryESQL?: () => void;
showPlainSpinner: boolean;
/** Handler for when try ES|QL is clicked and user has been navigated to try ES|QL in discover. */
onESQLNavigationComplete?: () => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ const PromptTryEsql = ({
NoDataViewsPromptComponentProps,
'onClickCreate' | 'onTryESQL' | 'esqlDocLink' | 'emptyPromptColor'
>) => {
if (!onTryESQL) {
// we need to handle the case where the Try ES|QL click handler is not set because
// onTryESQL is set via a useEffect that has asynchronous dependencies
return null;
}

// Load this illustration lazily
const Illustration = withSuspense(
React.lazy(() =>
Expand Down Expand Up @@ -136,14 +142,12 @@ const PromptTryEsql = ({

const footer = (
<>
{onTryESQL && (
<EuiButton onClick={onTryESQL} fill={true} data-test-subj="tryESQLLink">
<FormattedMessage
id="sharedUXPackages.noDataViewsPrompt.tryEsqlText"
defaultMessage="Try ES|QL"
/>
</EuiButton>
)}
<EuiButton onClick={onTryESQL} fill={true} data-test-subj="tryESQLLink">
<FormattedMessage
id="sharedUXPackages.noDataViewsPrompt.tryEsqlText"
defaultMessage="Try ES|QL"
/>
</EuiButton>
<EuiHorizontalRule />
{esqlDocLink && <DocumentationLink href={esqlDocLink} data-test-subj="docLinkEsql" />}
</>
Expand Down
14 changes: 11 additions & 3 deletions packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,20 @@ type CloseDataViewEditorFn = ReturnType<NoDataViewsPromptServices['openDataViewE
*/
export const NoDataViewsPrompt = ({
onDataViewCreated,
onESQLNavigationComplete,
allowAdHocDataView = false,
onTryESQL: onTryESQLParent,
onESQLNavigationComplete,
emptyPromptColor,
}: NoDataViewsPromptProps) => {
const { canCreateNewDataView, openDataViewEditor, dataViewsDocLink, onTryESQL, esqlDocLink } =
useServices();
const {
canCreateNewDataView,
openDataViewEditor,
dataViewsDocLink,
onTryESQL: onTryESQLService,
esqlDocLink,
} = useServices();

const onTryESQL = onTryESQLParent ?? onTryESQLService;

const closeDataViewEditor = useRef<CloseDataViewEditorFn>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class StorybookMock extends AbstractStorybookMock<
let onTryESQL;

if (canTryEsql !== false) {
onTryESQL = action('onTryESQL');
onTryESQL = action('onTryESQL-from-services');
}

return {
Expand Down
2 changes: 2 additions & 0 deletions packages/shared-ux/prompt/no_data_views/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ export interface NoDataViewsPromptProps {
allowAdHocDataView?: boolean;
/** Handler for successfully creating a new data view. */
onDataViewCreated: (dataView: unknown) => void;
/** Handler for someone wanting to try ES|QL. */
onTryESQL?: () => void;
/** Handler for when try ES|QL is clicked and user has been navigated to try ES|QL in discover. */
onESQLNavigationComplete?: () => void;
/** Empty prompt color **/
Expand Down

0 comments on commit db7cbae

Please sign in to comment.