Skip to content

Commit

Permalink
[Fleet] Fix disabling logic for "View Agents" button in agent activity (
Browse files Browse the repository at this point in the history
elastic#202968)

## Summary

I came across a small bug while testing Fleet agents activity: the "View
Agents" button is currently always disabled for agent policy changes.
This is because agent policy data has been modified to be fetched with
`noAgentCount: true` by default.

As getting the agent count involves a performance concern, this PR fixes
the logic that disables the "View Agents" button for policy change
actions instead. The behaviour is not as follows:
* For tag updates actions: button not showed (no change)
* For policy change actions
* If `action.nbAgentsActionCreated > 10000`: disable button and show
tooltip explaining why it's disabled
* Otherwise: enable button and show tooltip saying that these are the
agents _currently_ assigned to the policy (existing behaviour, known
limitation)
* For other types of actions (no change)
* If `action.nbAgentsActionCreated > 10000`: disable button and show
tooltip explaining why it's disabled
   * Otherwise: enable button, no tooltip

### Screenshots

![Screenshot 2024-12-05 at 10 56
40](https://github.com/user-attachments/assets/c5f4f868-cdac-4de7-a96d-f11afd803d87)

![Screenshot 2024-12-05 at 10 57
13](https://github.com/user-attachments/assets/91195e3a-4f5c-4a91-b9ff-ffb62818647f)

![Screenshot 2024-12-05 at 10 57
20](https://github.com/user-attachments/assets/9029b1b5-6983-4509-9b62-15e073546d42)
  • Loading branch information
jillguyonnet authored and CAWilson94 committed Dec 9, 2024
1 parent fe396b0 commit 38f1882
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
EuiSpacer,
} from '@elastic/eui';

import type { ActionStatus, AgentPolicy } from '../../../../../types';
import type { ActionStatus } from '../../../../../types';

import { ViewErrors } from '../view_errors';

Expand All @@ -34,8 +34,7 @@ import { ViewAgentsButton } from './view_agents_button';
export const ActivityItem: React.FunctionComponent<{
action: ActionStatus;
onClickViewAgents: (action: ActionStatus) => void;
agentPolicies: AgentPolicy[];
}> = ({ action, onClickViewAgents, agentPolicies }) => {
}> = ({ action, onClickViewAgents }) => {
const completeTitle =
action.type === 'POLICY_CHANGE' && action.nbAgentsActioned === 0 ? (
<EuiText>
Expand Down Expand Up @@ -248,11 +247,7 @@ export const ActivityItem: React.FunctionComponent<{
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="xs" />
<ViewAgentsButton
action={action}
onClickViewAgents={onClickViewAgents}
agentPolicies={agentPolicies}
/>
<ViewAgentsButton action={action} onClickViewAgents={onClickViewAgents} />
</EuiPanel>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { ReactNode } from 'react';
import React from 'react';
import { EuiText, EuiPanel } from '@elastic/eui';

import type { ActionStatus, AgentPolicy } from '../../../../../types';
import type { ActionStatus } from '../../../../../types';

import { UpgradeInProgressActivityItem } from './upgrade_in_progress_activity_item';
import { ActivityItem } from './activity_item';
Expand All @@ -19,8 +19,7 @@ export const ActivitySection: React.FunctionComponent<{
actions: ActionStatus[];
abortUpgrade: (action: ActionStatus) => Promise<void>;
onClickViewAgents: (action: ActionStatus) => void;
agentPolicies: AgentPolicy[];
}> = ({ title, actions, abortUpgrade, onClickViewAgents, agentPolicies }) => {
}> = ({ title, actions, abortUpgrade, onClickViewAgents }) => {
return (
<>
<EuiPanel color="subdued" hasBorder={true} borderRadius="none">
Expand All @@ -41,7 +40,6 @@ export const ActivitySection: React.FunctionComponent<{
action={currentAction}
key={currentAction.actionId}
onClickViewAgents={onClickViewAgents}
agentPolicies={agentPolicies}
/>
)
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import styled from 'styled-components';

import { FormattedDate, FormattedMessage } from '@kbn/i18n-react';

import type { ActionStatus, AgentPolicy } from '../../../../../types';
import type { ActionStatus } from '../../../../../types';

import { Loading } from '../../../components';

Expand Down Expand Up @@ -51,7 +51,6 @@ export const FlyoutBody: React.FunctionComponent<{
onClickShowMore: () => void;
dateFilter: moment.Moment | null;
onChangeDateFilter: (date: moment.Moment | null) => void;
agentPolicies: AgentPolicy[];
}> = ({
isFirstLoading,
currentActions,
Expand All @@ -61,7 +60,6 @@ export const FlyoutBody: React.FunctionComponent<{
onClickShowMore,
dateFilter,
onChangeDateFilter,
agentPolicies,
}) => {
const scrollToTopRef = React.useRef<HTMLDivElement>(null);
React.useEffect(() => {
Expand Down Expand Up @@ -164,7 +162,6 @@ export const FlyoutBody: React.FunctionComponent<{
actions={inProgressActions}
abortUpgrade={abortUpgrade}
onClickViewAgents={onClickViewAgents}
agentPolicies={agentPolicies}
/>
) : null}
{todayActions.length > 0 ? (
Expand All @@ -178,7 +175,6 @@ export const FlyoutBody: React.FunctionComponent<{
actions={todayActions}
abortUpgrade={abortUpgrade}
onClickViewAgents={onClickViewAgents}
agentPolicies={agentPolicies}
/>
) : null}
{Object.keys(otherDays).map((day) => (
Expand All @@ -188,7 +184,6 @@ export const FlyoutBody: React.FunctionComponent<{
actions={otherDays[day]}
abortUpgrade={abortUpgrade}
onClickViewAgents={onClickViewAgents}
agentPolicies={agentPolicies}
/>
))}
</EuiFlexGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ describe('AgentActivityFlyout', () => {
refreshAgentActivity={refreshAgentActivity}
setSearch={mockSetSearch}
setSelectedStatus={mockSetSelectedStatus}
agentPolicies={[]}
/>
</IntlProvider>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ import { getKuery } from '../../utils/get_kuery';

import { AGENT_STATUSES } from '../../../services/agent_status';

import type { AgentPolicy } from '../../../../../types';

import { FlyoutBody } from './flyout_body';

const FlyoutFooterWPadding = styled(EuiFlyoutFooter)`
Expand All @@ -48,15 +46,7 @@ export const AgentActivityFlyout: React.FunctionComponent<{
refreshAgentActivity: boolean;
setSearch: (search: string) => void;
setSelectedStatus: (status: string[]) => void;
agentPolicies: AgentPolicy[];
}> = ({
onClose,
onAbortSuccess,
refreshAgentActivity,
setSearch,
setSelectedStatus,
agentPolicies,
}) => {
}> = ({ onClose, onAbortSuccess, refreshAgentActivity, setSearch, setSelectedStatus }) => {
const { notifications } = useStartServices();
const { data: agentPoliciesData } = useGetAgentPolicies({
perPage: SO_SEARCH_LIMIT,
Expand Down Expand Up @@ -167,7 +157,6 @@ export const AgentActivityFlyout: React.FunctionComponent<{
onClickShowMore={onClickShowMore}
dateFilter={dateFilter}
onChangeDateFilter={onChangeDateFilter}
agentPolicies={agentPolicies}
/>
<FlyoutFooterWPadding>
<EuiFlexGroup justifyContent="flexStart">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,17 @@ import React, { useMemo } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui';

import type { ActionStatus, AgentPolicy } from '../../../../../types';
import type { ActionStatus } from '../../../../../types';

const MAX_VIEW_AGENTS_COUNT = 1000;

export const ViewAgentsButton: React.FunctionComponent<{
action: ActionStatus;
onClickViewAgents: (action: ActionStatus) => void;
agentPolicies?: AgentPolicy[];
}> = ({ action, onClickViewAgents, agentPolicies }) => {
}> = ({ action, onClickViewAgents }) => {
const isDisabled = useMemo(() => {
if (action.type !== 'POLICY_CHANGE') {
return action.nbAgentsActionCreated > MAX_VIEW_AGENTS_COUNT;
}

const actionPolicyId = action.actionId.split(':')[0];
return agentPolicies?.find((agentPolicy) => agentPolicy.id === actionPolicyId)?.agents === 0;
}, [action, agentPolicies]);
return action.nbAgentsActionCreated > MAX_VIEW_AGENTS_COUNT;
}, [action]);

if (action.type === 'UPDATE_TAGS') {
return null;
Expand All @@ -46,8 +40,22 @@ export const ViewAgentsButton: React.FunctionComponent<{
</EuiButtonEmpty>
);

if (action.type !== 'POLICY_CHANGE' && !isDisabled) {
return button;
if (isDisabled) {
return (
<EuiToolTip
content={
<FormattedMessage
id="xpack.fleet.agentActivityFlyout.viewAgentsButtonDisabledMaxTooltip"
defaultMessage="The view agents feature is only available for action impacting less than {agentCount} agents"
values={{
agentCount: MAX_VIEW_AGENTS_COUNT,
}}
/>
}
>
{button}
</EuiToolTip>
);
}

if (action.type === 'POLICY_CHANGE') {
Expand All @@ -65,19 +73,5 @@ export const ViewAgentsButton: React.FunctionComponent<{
);
}

return (
<EuiToolTip
content={
<FormattedMessage
id="xpack.fleet.agentActivityFlyout.viewAgentsButtonDisabledMaxTooltip"
defaultMessage="The view agents feature is only available for action impacting less than {agentCount} agents"
values={{
agentCount: MAX_VIEW_AGENTS_COUNT,
}}
/>
}
>
{button}
</EuiToolTip>
);
return button;
};
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,6 @@ export const AgentListPage: React.FunctionComponent<{}> = () => {
refreshAgentActivity={isLoading}
setSearch={setSearch}
setSelectedStatus={setSelectedStatus}
agentPolicies={allAgentPolicies}
/>
</EuiPortal>
) : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const GetAgentPoliciesRequestSchema = {
schema.boolean({
meta: { description: 'use withAgentCount instead', deprecated: true },
})
), //
),
withAgentCount: schema.maybe(
schema.boolean({
meta: { description: 'get policies with agent count' },
Expand Down

0 comments on commit 38f1882

Please sign in to comment.