-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
[ML] Transforms: Adds a link to discover from the transform list to the actions menu. #97805
Changes from 3 commits
453057d
92ae38b
7882f2c
21244e7
171a65c
bb30f3f
69fabdc
78b5939
189cbb2
dc8e95b
a150df4
2616008
233b0b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -12,21 +12,31 @@ import rison from 'rison-node'; | |||
import { SECTION_SLUG } from '../constants'; | ||||
|
||||
/** | ||||
* Gets a url for navigating to Discover page. | ||||
* Gets url state for navigating to Discover page with optional link to a specific index pattern. | ||||
* @param indexPatternId Index pattern ID. | ||||
* @param baseUrl Base url. | ||||
*/ | ||||
export function getDiscoverUrl(indexPatternId: string, baseUrl: string): string { | ||||
export function getDiscoverUrlState(indexPatternId?: string): string { | ||||
const _g = rison.encode({}); | ||||
|
||||
// Add the index pattern ID to the appState part of the URL. | ||||
const _a = rison.encode({ | ||||
index: indexPatternId, | ||||
}); | ||||
|
||||
const hash = `/discover#?_g=${_g}&_a=${_a}`; | ||||
const _a = rison.encode( | ||||
typeof indexPatternId === 'string' | ||||
? { | ||||
index: indexPatternId, | ||||
} | ||||
: {} | ||||
); | ||||
|
||||
return `_g=${_g}&_a=${_a}`; | ||||
} | ||||
|
||||
return `${baseUrl}/app${hash}`; | ||||
/** | ||||
* Gets a url for navigating to Discover page. | ||||
* @param indexPatternId Index pattern ID. | ||||
* @param baseUrl Base url. | ||||
*/ | ||||
export function getDiscoverUrl(indexPatternId: string, baseUrl: string): string { | ||||
return `${baseUrl}/app/discover#?${getDiscoverUrlState(indexPatternId)}`; | ||||
} | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. discover plugin provides a URL generator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good find, we hadn't used those generators yet in the transform plugin. I refactored to make use of it, the result is that these utils are not necessary anymore 🥳 - related update in bb30f3f. |
||||
|
||||
export const RedirectToTransformManagement: FC = () => <Redirect to={`/${SECTION_SLUG.HOME}`} />; | ||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* | ||
* 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; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { cloneDeep } from 'lodash'; | ||
import React from 'react'; | ||
import { IntlProvider } from 'react-intl'; | ||
|
||
import { render, waitFor, screen } from '@testing-library/react'; | ||
|
||
import { TransformListRow } from '../../../../common'; | ||
import { isDiscoverActionDisabled, DiscoverActionName } from './discover_action_name'; | ||
|
||
import transformListRow from '../../../../common/__mocks__/transform_list_row.json'; | ||
|
||
jest.mock('../../../../../shared_imports'); | ||
jest.mock('../../../../../app/app_dependencies'); | ||
|
||
// @ts-expect-error mock data is too loosely typed | ||
const item: TransformListRow = transformListRow; | ||
|
||
describe('Transform: Transform List Actions isDiscoverActionDisabled()', () => { | ||
it('should be disabled when more than one item is passed in', () => { | ||
expect(isDiscoverActionDisabled([item, item], false, true)).toBe(true); | ||
}); | ||
it('should be disabled when forceDisable is true', () => { | ||
expect(isDiscoverActionDisabled([item], true, true)).toBe(true); | ||
}); | ||
it('should be disabled when the index pattern is not available', () => { | ||
expect(isDiscoverActionDisabled([item], false, false)).toBe(true); | ||
}); | ||
it('should be disabled when the transform started but has no index pattern', () => { | ||
const itemCopy = cloneDeep(item); | ||
itemCopy.stats.state = 'started'; | ||
expect(isDiscoverActionDisabled([itemCopy], false, false)).toBe(true); | ||
}); | ||
it('should be enabled when the transform started and has an index pattern', () => { | ||
const itemCopy = cloneDeep(item); | ||
itemCopy.stats.state = 'started'; | ||
expect(isDiscoverActionDisabled([itemCopy], false, true)).toBe(false); | ||
}); | ||
it('should be enabled when the index pattern is available', () => { | ||
expect(isDiscoverActionDisabled([item], false, true)).toBe(false); | ||
}); | ||
}); | ||
|
||
describe('Transform: Transform List Actions <StopAction />', () => { | ||
it('renders an enabled button', async () => { | ||
// prepare | ||
render( | ||
<IntlProvider locale="en"> | ||
<DiscoverActionName items={[item]} /> | ||
</IntlProvider> | ||
); | ||
|
||
// assert | ||
await waitFor(() => { | ||
expect( | ||
screen.queryByTestId('transformDiscoverActionNameText disabled') | ||
).not.toBeInTheDocument(); | ||
expect(screen.queryByTestId('transformDiscoverActionNameText enabled')).toBeInTheDocument(); | ||
expect(screen.queryByText('View in Discover')).toBeInTheDocument(); | ||
}); | ||
}); | ||
|
||
it('renders a disabled button', async () => { | ||
// prepare | ||
const itemCopy = cloneDeep(item); | ||
itemCopy.stats.checkpointing.last.checkpoint = 0; | ||
render( | ||
<IntlProvider locale="en"> | ||
<DiscoverActionName items={[itemCopy]} /> | ||
</IntlProvider> | ||
); | ||
|
||
// assert | ||
await waitFor(() => { | ||
expect(screen.queryByTestId('transformDiscoverActionNameText disabled')).toBeInTheDocument(); | ||
expect( | ||
screen.queryByTestId('transformDiscoverActionNameText enabled') | ||
).not.toBeInTheDocument(); | ||
expect(screen.queryByText('View in Discover')).toBeInTheDocument(); | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* 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; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import React, { FC } from 'react'; | ||
import { i18n } from '@kbn/i18n'; | ||
import { EuiToolTip } from '@elastic/eui'; | ||
|
||
import { TRANSFORM_STATE } from '../../../../../../common/constants'; | ||
|
||
import { getTransformProgress, TransformListRow } from '../../../../common'; | ||
|
||
export const discoverActionNameText = i18n.translate( | ||
'xpack.transform.transformList.discoverActionNameText', | ||
{ | ||
defaultMessage: 'View in Discover', | ||
} | ||
); | ||
|
||
export const isDiscoverActionDisabled = ( | ||
items: TransformListRow[], | ||
forceDisable: boolean, | ||
indexPatternExists: boolean | ||
) => { | ||
if (items.length !== 1) { | ||
return true; | ||
} | ||
|
||
const item = items[0]; | ||
|
||
// Disable discover action if it's a batch transform and was never started | ||
const stoppedTransform = item.stats.state === TRANSFORM_STATE.STOPPED; | ||
const transformProgress = getTransformProgress(item); | ||
const isBatchTransform = typeof item.config.sync === 'undefined'; | ||
const transformNeverStarted = | ||
stoppedTransform === true && transformProgress === undefined && isBatchTransform === true; | ||
|
||
return forceDisable === true || indexPatternExists === false || transformNeverStarted === true; | ||
}; | ||
|
||
export interface DiscoverActionNameProps { | ||
items: TransformListRow[]; | ||
} | ||
export const DiscoverActionName: FC<DiscoverActionNameProps> = ({ items }) => { | ||
const isBulkAction = items.length > 1; | ||
|
||
const item = items[0]; | ||
|
||
// Disable discover action if it's a batch transform and was never started | ||
const stoppedTransform = item.stats.state === TRANSFORM_STATE.STOPPED; | ||
const transformProgress = getTransformProgress(item); | ||
const isBatchTransform = typeof item.config.sync === 'undefined'; | ||
const transformNeverStarted = | ||
stoppedTransform && transformProgress === undefined && isBatchTransform === true; | ||
|
||
let disabledTransformMessage; | ||
if (isBulkAction === true) { | ||
disabledTransformMessage = i18n.translate( | ||
'xpack.transform.transformList.discoverTransformBulkToolTip', | ||
{ | ||
defaultMessage: 'Links to discover are not supported as a bulk action.', | ||
peteharverson marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
); | ||
} else { | ||
disabledTransformMessage = i18n.translate( | ||
'xpack.transform.transformList.discoverTransformToolTip', | ||
{ | ||
defaultMessage: `The transform needs to be started before it's available in Discover.`, | ||
} | ||
); | ||
} | ||
|
||
if (transformNeverStarted) { | ||
return ( | ||
<EuiToolTip position="top" content={disabledTransformMessage}> | ||
<span data-test-subj="transformDiscoverActionNameText disabled"> | ||
{discoverActionNameText} | ||
</span> | ||
</EuiToolTip> | ||
); | ||
} | ||
|
||
return ( | ||
<span data-test-subj="transformDiscoverActionNameText enabled">{discoverActionNameText}</span> | ||
); | ||
}; |
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; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
export { useDiscoverAction } from './use_action_discover'; | ||
export { DiscoverActionName } from './discover_action_name'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mind setting the mock if needed on your own tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I refactored the code to apply that mock in the transform plugin code (171a65c)