fix status command to not flicker and to show pending message (#135583)

This commit is contained in:
Paul Tavares 2022-07-06 13:59:09 -04:00 committed by GitHub
parent 9c8468eae2
commit ad5baf46a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -6,7 +6,7 @@
*/ */
import React, { memo, useEffect, useMemo } from 'react'; import React, { memo, useEffect, useMemo } from 'react';
import { EuiCallOut, EuiFieldText, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react'; import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n'; import { i18n } from '@kbn/i18n';
import type { HttpFetchError } from '@kbn/core/public'; import type { HttpFetchError } from '@kbn/core/public';
@ -33,21 +33,25 @@ export const EndpointStatusActionResult = memo<
}, },
EndpointCommandDefinitionMeta EndpointCommandDefinitionMeta
> >
>(({ command, status, setStatus, store, setStore }) => { >(({ command, status, setStatus, store, setStore, ResultComponent }) => {
const endpointId = command.commandDefinition?.meta?.endpointId as string; const endpointId = command.commandDefinition?.meta?.endpointId as string;
const { endpointPendingActions, endpointDetails, detailsFetchError, apiCalled } = store; const { endpointPendingActions, endpointDetails, detailsFetchError, apiCalled } = store;
const isPending = status === 'pending'; const isPending = status === 'pending';
const queryKey = useMemo(() => {
return uuidV4();
}, []);
const { const {
data: fetchedEndpointDetails,
error: fetchedDetailsError,
isFetching, isFetching,
isFetched, isFetched,
refetch: fetchEndpointDetails, } = useGetEndpointDetails(endpointId, { enabled: isPending, queryKey });
} = useGetEndpointDetails(endpointId, { enabled: false });
const { refetch: fetchEndpointPendingActionsSummary } = useGetEndpointPendingActionsSummary( const { data: fetchedPendingActionsSummary } = useGetEndpointPendingActionsSummary([endpointId], {
[endpointId], enabled: isPending,
{ enabled: false } queryKey,
); });
const pendingIsolationActions = useMemo< const pendingIsolationActions = useMemo<
Pick<Required<EndpointHostIsolationStatusProps>, 'pendingIsolate' | 'pendingUnIsolate'> Pick<Required<EndpointHostIsolationStatusProps>, 'pendingIsolate' | 'pendingUnIsolate'>
@ -67,70 +71,64 @@ export const EndpointStatusActionResult = memo<
}, [endpointPendingActions?.data]); }, [endpointPendingActions?.data]);
useEffect(() => { useEffect(() => {
if (!apiCalled) { if (!isPending) {
setStore((prevState) => { setStore((prevState) => {
return { return {
...prevState, ...prevState,
apiCalled: true, apiCalled: true,
}; };
}); });
// Using a unique `queryKey` here and below so that data is NOT updated
// from cache when future requests for this endpoint ID is done again.
fetchEndpointDetails({ queryKey: uuidV4() })
.then(({ data }) => {
setStore((prevState) => {
return {
...prevState,
endpointDetails: data,
};
});
})
.catch((err) => {
setStore((prevState) => {
return {
...prevState,
detailsFetchError: err,
};
});
});
fetchEndpointPendingActionsSummary({ queryKey: uuidV4() }).then(({ data }) => {
setStore((prevState) => {
return {
...prevState,
endpointPendingActions: data,
};
});
});
} }
}, [apiCalled, fetchEndpointDetails, fetchEndpointPendingActionsSummary, setStore]); }, [apiCalled, isPending, setStore]);
// update command store if endpoint details fetch api call completed
useEffect(() => { useEffect(() => {
if (isFetched && isPending) { if (isFetched && isPending) {
setStatus(detailsFetchError ? 'error' : 'success'); setStatus(detailsFetchError ? 'error' : 'success');
setStore((prevState) => {
return {
...prevState,
endpointDetails: fetchedEndpointDetails,
detailsFetchError: fetchedDetailsError ?? undefined,
};
});
} }
}, [detailsFetchError, isFetched, setStatus, isPending]); }, [
detailsFetchError,
isFetched,
setStatus,
isPending,
setStore,
fetchedEndpointDetails,
fetchedDetailsError,
]);
if (isFetching) { // Update the store once we get back pending actions for this endpoint
return null; useEffect(() => {
if (fetchedPendingActionsSummary) {
setStore((prevState) => {
return {
...prevState,
endpointPendingActions: fetchedPendingActionsSummary,
};
});
} }
}, [fetchedPendingActionsSummary, setStore]);
if (detailsFetchError) { if (detailsFetchError) {
return ( return (
<EuiCallOut> <ResultComponent showAs="failure">
<EuiFieldText>
<FormattedError error={detailsFetchError} /> <FormattedError error={detailsFetchError} />
</EuiFieldText> </ResultComponent>
</EuiCallOut>
); );
} }
if (!endpointDetails) { if (isFetching || !endpointDetails) {
return null; return <ResultComponent showAs="pending" />;
} }
return ( return (
<ResultComponent showTitle={false}>
<EuiFlexGroup wrap={false} responsive={false}> <EuiFlexGroup wrap={false} responsive={false}>
<EuiFlexItem grow={false}> <EuiFlexItem grow={false}>
<EuiText size="s"> <EuiText size="s">
@ -184,6 +182,7 @@ export const EndpointStatusActionResult = memo<
</EuiText> </EuiText>
</EuiFlexItem> </EuiFlexItem>
</EuiFlexGroup> </EuiFlexGroup>
</ResultComponent>
); );
}); });
EndpointStatusActionResult.displayName = 'EndpointStatusActionResult'; EndpointStatusActionResult.displayName = 'EndpointStatusActionResult';