-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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: Improves transform list reloading behavior. #164296
[ML] Transforms: Improves transform list reloading behavior. #164296
Conversation
f8efbfb
to
270b8a2
Compare
💛 Build succeeded, but was flaky
Failed CI StepsTest Failures
Metrics [docs]Module Count
Async chunks
Page load bundle
Unknown metric groupsESLint disabled in files
ESLint disabled line counts
Total ESLint disabled count
History
To update your PR or re-run it, just comment with: cc @walterra |
8022e8f
to
8f76e78
Compare
<EuiFlexGroup justifyContent="spaceAround"> | ||
<EuiFlexItem grow={false}> | ||
<EuiPageContent verticalPosition="center" horizontalPosition="center" color="danger"> |
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 think you can use EuiPageTemplate.EmptyPrompt
instead
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.
Good catch, must have missed it when I merged in your PR that fixed those, updated in 9b02239.
<EuiButtonEmpty onClick={openModal}> | ||
{!inline && ( | ||
<> | ||
<pre>{previewText}</pre>{' '} |
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.
<pre>{previewText}</pre>{' '} | |
<pre>{previewText}</pre> |
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.
Updated in a47947c.
const { canDeleteIndex: userCanDeleteIndex } = useTransformCapabilities(); | ||
|
||
const userCanDeleteDataView = | ||
(capabilities.savedObjectsManagement && capabilities.savedObjectsManagement.delete === true) || |
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.
(capabilities.savedObjectsManagement && capabilities.savedObjectsManagement.delete === true) || | |
(capabilities.savedObjectsManagement?.delete === true) || |
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.
Updated in 4efc4bd.
|
||
const userCanDeleteDataView = | ||
(capabilities.savedObjectsManagement && capabilities.savedObjectsManagement.delete === true) || | ||
(capabilities.indexPatterns && capabilities.indexPatterns.save === true); |
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.
(capabilities.indexPatterns && capabilities.indexPatterns.save === true); | |
capabilities.indexPatterns?.save === true; |
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.
Updated in 4efc4bd.
|
||
return useQuery<string[], IHttpFetchError>( | ||
[TRANSFORM_REACT_QUERY_KEYS.GET_DATA_VIEW_TITLES], | ||
() => data.dataViews.getTitles() |
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.
() => data.dataViews.getTitles() | |
data.dataViews.getTitles |
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.
This would give a TS error because the useQuery
callback would pass on incompatible arguments.
useEffect(() => { | ||
if (dataViewFieldsIsLoading && !dataViewFieldsIsError) { | ||
setErrorMessage(''); | ||
setStatus(INDEX_STATUS.LOADING); | ||
} else if (dataViewFieldsError !== null) { | ||
setErrorMessage(getErrorMessage(dataViewFieldsError)); | ||
setStatus(INDEX_STATUS.ERROR); | ||
} else if ( | ||
!dataViewFieldsIsLoading && | ||
!dataViewFieldsIsError && | ||
dataViewFieldsData !== undefined | ||
) { | ||
const isCrossClusterSearch = indexPattern.includes(':'); | ||
const isMissingFields = dataViewFieldsData.hits.hits.every( | ||
(d) => typeof d.fields === 'undefined' | ||
); | ||
|
||
if (!isEsSearchResponse(resp)) { | ||
setErrorMessage(getErrorMessage(resp)); | ||
setStatus(INDEX_STATUS.ERROR); | ||
return; | ||
} | ||
const docs = resp.hits.hits.map((d) => getProcessedFields(d.fields ?? {})); | ||
isMissingFields = resp.hits.hits.every((d) => typeof d.fields === 'undefined'); | ||
setCcsWarning(isCrossClusterSearch && isMissingFields); | ||
setStatus(INDEX_STATUS.LOADED); | ||
} | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [dataViewFieldsData, dataViewFieldsError, dataViewFieldsIsError, dataViewFieldsIsLoading]); |
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.
The entire effect looks very complex. Essentially it derives error message and status.
Can we get rid of the state and use memo instead? e.g.
const errorMessage = useMemo(() => {...}, [dataViewFieldsIsLoading, dataViewFieldsIsError]);
); | ||
|
||
useEffect(() => { | ||
if (dataGridDataIsLoading && !dataGridDataIsError) { |
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.
same as above
isLoading, | ||
} = useGetTransformsPreview(previewRequest, validationStatus.isValid); | ||
|
||
useEffect(() => { |
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 reckon we should avoid such massive effects. It seems like it can be broken down in independent variables
|
||
const transformConfigs = await api.getTransform(transformId); | ||
if (isHttpFetchError(transformConfigs)) { | ||
useEffect(() => { |
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.
same about this effect
@darnautov I agree those |
💔 Build FailedFailed CI Steps
Metrics [docs]Module Count
Async chunks
Page load bundle
Unknown metric groupsESLint disabled in files
References to deprecated APIs
Total ESLint disabled count
History
To update your PR or re-run it, just comment with: cc @walterra |
…164296) ## Summary - If the transform list fails to load, it does no longer show a non-refreshable full page error. Instead the error is shown in an inline callout and the refresh button is still present. - `AuthorizationProvider` is gone and has been replaced by a custom hook `useTransformCapabilities`. All client side code no longer relies on `privileges` being present but makes use of `capabilities` (like `canGetTransform` etc.). The custom route to fetch privileges and capabilities is also gone, instead capabilities are retrieved from Kibana's own `application.capabilities.transform` which we register server side. - Refactors all remote data fetching to use `react-query`. This gets rid of the custom code to refresh the transform list using observables, instead all CRUD actions now make use of `react-query`'s `useMutation` and trigger a cache invalidation of the transform list data to initiate a refetch. The `useApi` hook is gone, instead we now have specific hooks for data fetching that wrap `useQuery` (`useGetTransform`, `useGetTransformStats` etc.) and the existing hooks for actions have been refactored to use `useMutation` (`useStartTransforms`, `useStopTransforms` etc.). - Toasts for "success" messages have been removed. - All tests that made use of `toMatchSnapshot` have been refactored away from `enzyme` to `react-testing-lib` and no longer rely on snapshots, instead we make basic assertions on the rendered components. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
Summary
Fixes #164303 (Fix transforms in serverless projects).
Fixes #163145 (Improve transformlist reloading behavior).
Part of #153288 (Migrate snapshot tests using enzyme to use @testing-library/react).
Before:
After:
AuthorizationProvider
is gone and has been replaced by a custom hookuseTransformCapabilities
. All client side code no longer relies onprivileges
being present but makes use ofcapabilities
(likecanGetTransform
etc.). The custom route to fetch privileges and capabilities is also gone, instead capabilities are retrieved from Kibana's ownapplication.capabilities.transform
which we register server side.react-query
. This gets rid of the custom code to refresh the transform list using observables, instead all CRUD actions now make use ofreact-query
'suseMutation
and trigger a cache invalidation of the transform list data to initiate a refetch. TheuseApi
hook is gone, instead we now have specific hooks for data fetching that wrapuseQuery
(useGetTransform
,useGetTransformStats
etc.) and the existing hooks for actions have been refactored to useuseMutation
(useStartTransforms
,useStopTransforms
etc.).toMatchSnapshot
have been refactored away fromenzyme
toreact-testing-lib
and no longer rely on snapshots, instead we make basic assertions on the rendered components.Checklist