mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
fix status command to not flicker and to show pending message (#135583)
This commit is contained in:
parent
9c8468eae2
commit
ad5baf46a3
1 changed files with 100 additions and 101 deletions
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
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 { i18n } from '@kbn/i18n';
|
||||
import type { HttpFetchError } from '@kbn/core/public';
|
||||
|
@ -33,21 +33,25 @@ export const EndpointStatusActionResult = memo<
|
|||
},
|
||||
EndpointCommandDefinitionMeta
|
||||
>
|
||||
>(({ command, status, setStatus, store, setStore }) => {
|
||||
>(({ command, status, setStatus, store, setStore, ResultComponent }) => {
|
||||
const endpointId = command.commandDefinition?.meta?.endpointId as string;
|
||||
const { endpointPendingActions, endpointDetails, detailsFetchError, apiCalled } = store;
|
||||
const isPending = status === 'pending';
|
||||
const queryKey = useMemo(() => {
|
||||
return uuidV4();
|
||||
}, []);
|
||||
|
||||
const {
|
||||
data: fetchedEndpointDetails,
|
||||
error: fetchedDetailsError,
|
||||
isFetching,
|
||||
isFetched,
|
||||
refetch: fetchEndpointDetails,
|
||||
} = useGetEndpointDetails(endpointId, { enabled: false });
|
||||
} = useGetEndpointDetails(endpointId, { enabled: isPending, queryKey });
|
||||
|
||||
const { refetch: fetchEndpointPendingActionsSummary } = useGetEndpointPendingActionsSummary(
|
||||
[endpointId],
|
||||
{ enabled: false }
|
||||
);
|
||||
const { data: fetchedPendingActionsSummary } = useGetEndpointPendingActionsSummary([endpointId], {
|
||||
enabled: isPending,
|
||||
queryKey,
|
||||
});
|
||||
|
||||
const pendingIsolationActions = useMemo<
|
||||
Pick<Required<EndpointHostIsolationStatusProps>, 'pendingIsolate' | 'pendingUnIsolate'>
|
||||
|
@ -67,123 +71,118 @@ export const EndpointStatusActionResult = memo<
|
|||
}, [endpointPendingActions?.data]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!apiCalled) {
|
||||
if (!isPending) {
|
||||
setStore((prevState) => {
|
||||
return {
|
||||
...prevState,
|
||||
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(() => {
|
||||
if (isFetched && isPending) {
|
||||
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) {
|
||||
return null;
|
||||
}
|
||||
// Update the store once we get back pending actions for this endpoint
|
||||
useEffect(() => {
|
||||
if (fetchedPendingActionsSummary) {
|
||||
setStore((prevState) => {
|
||||
return {
|
||||
...prevState,
|
||||
endpointPendingActions: fetchedPendingActionsSummary,
|
||||
};
|
||||
});
|
||||
}
|
||||
}, [fetchedPendingActionsSummary, setStore]);
|
||||
|
||||
if (detailsFetchError) {
|
||||
return (
|
||||
<EuiCallOut>
|
||||
<EuiFieldText>
|
||||
<FormattedError error={detailsFetchError} />
|
||||
</EuiFieldText>
|
||||
</EuiCallOut>
|
||||
<ResultComponent showAs="failure">
|
||||
<FormattedError error={detailsFetchError} />
|
||||
</ResultComponent>
|
||||
);
|
||||
}
|
||||
|
||||
if (!endpointDetails) {
|
||||
return null;
|
||||
if (isFetching || !endpointDetails) {
|
||||
return <ResultComponent showAs="pending" />;
|
||||
}
|
||||
|
||||
return (
|
||||
<EuiFlexGroup wrap={false} responsive={false}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size="s">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpointResponseActions.status.agentStatus"
|
||||
defaultMessage="Agent status"
|
||||
<ResultComponent showTitle={false}>
|
||||
<EuiFlexGroup wrap={false} responsive={false}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size="s">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpointResponseActions.status.agentStatus"
|
||||
defaultMessage="Agent status"
|
||||
/>
|
||||
</EuiText>
|
||||
<EndpointAgentAndIsolationStatus
|
||||
status={endpointDetails.host_status}
|
||||
isIsolated={Boolean(endpointDetails.metadata.Endpoint.state?.isolation)}
|
||||
{...pendingIsolationActions}
|
||||
/>
|
||||
</EuiText>
|
||||
<EndpointAgentAndIsolationStatus
|
||||
status={endpointDetails.host_status}
|
||||
isIsolated={Boolean(endpointDetails.metadata.Endpoint.state?.isolation)}
|
||||
{...pendingIsolationActions}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size="s">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpointResponseActions.status.version"
|
||||
defaultMessage="Version"
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size="s">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpointResponseActions.status.version"
|
||||
defaultMessage="Version"
|
||||
/>
|
||||
</EuiText>
|
||||
<EuiText>{endpointDetails.metadata.agent.version}</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size="s">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpointResponseActions.status.policyStatus"
|
||||
defaultMessage="Policy status"
|
||||
/>
|
||||
</EuiText>
|
||||
<EndpointAppliedPolicyStatus
|
||||
policyApplied={endpointDetails.metadata.Endpoint.policy.applied}
|
||||
/>
|
||||
</EuiText>
|
||||
<EuiText>{endpointDetails.metadata.agent.version}</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size="s">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpointResponseActions.status.policyStatus"
|
||||
defaultMessage="Policy status"
|
||||
/>
|
||||
</EuiText>
|
||||
<EndpointAppliedPolicyStatus
|
||||
policyApplied={endpointDetails.metadata.Endpoint.policy.applied}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiText size="s">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpointResponseActions.status.lastActive"
|
||||
defaultMessage="Last active"
|
||||
/>
|
||||
</EuiText>
|
||||
<EuiText>
|
||||
<FormattedDate
|
||||
fieldName={i18n.translate(
|
||||
'xpack.securitySolution.endpointResponseActions.status.lastActive',
|
||||
{ defaultMessage: 'Last active' }
|
||||
)}
|
||||
value={endpointDetails.metadata['@timestamp']}
|
||||
className="eui-textTruncate"
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiText size="s">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpointResponseActions.status.lastActive"
|
||||
defaultMessage="Last active"
|
||||
/>
|
||||
</EuiText>
|
||||
<EuiText>
|
||||
<FormattedDate
|
||||
fieldName={i18n.translate(
|
||||
'xpack.securitySolution.endpointResponseActions.status.lastActive',
|
||||
{ defaultMessage: 'Last active' }
|
||||
)}
|
||||
value={endpointDetails.metadata['@timestamp']}
|
||||
className="eui-textTruncate"
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</ResultComponent>
|
||||
);
|
||||
});
|
||||
EndpointStatusActionResult.displayName = 'EndpointStatusActionResult';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue