From 17ecb04dce72585f7ada69de7af3065cf4cc17d1 Mon Sep 17 00:00:00 2001 From: John Schulz Date: Mon, 19 Apr 2021 09:43:43 -0400 Subject: [PATCH] [Fleet] Filter hosted policies from menu (#97380) ## Summary * 4C & 7C from https://github.com/elastic/kibana/issues/91906 about hiding hosted agent policy from select menus * Also changed reassign agent to new policy UI from flyout to modal as requested
Screenshots

Current

Screen Shot 2021-04-16 at 1 37 02 PM

PR

Screen Shot 2021-04-16 at 1 43 51 PM

current

Screen Shot 2021-04-16 at 1 44 41 PM

PR

Screen Shot 2021-04-16 at 1 50 28 PM

current

Screen Shot 2021-04-16 at 1 35 48 PM

PR

Screen Shot 2021-04-16 at 2 35 15 PM Screen Shot 2021-04-16 at 3 24 16 PM
### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/master/packages/kbn-i18n/README.md) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../fleet/components/package_icon.tsx | 15 +- .../step_select_agent_policy.tsx | 6 +- .../components/actions_menu.tsx | 4 +- .../components/bulk_actions.tsx | 4 +- .../sections/agents/agent_list_page/index.tsx | 6 +- .../agent_enrollment_flyout/steps.tsx | 5 +- .../agent_reassign_policy_flyout/index.tsx | 175 ------------------ .../agent_reassign_policy_modal/index.tsx | 159 ++++++++++++++++ .../sections/agents/components/index.tsx | 2 +- 9 files changed, 189 insertions(+), 187 deletions(-) delete mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_reassign_policy_flyout/index.tsx create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_reassign_policy_modal/index.tsx diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/package_icon.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/package_icon.tsx index cb0b02527f756..e7fd1da394bb3 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/components/package_icon.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/components/package_icon.tsx @@ -14,7 +14,18 @@ import { usePackageIconType } from '../hooks'; export const PackageIcon: React.FunctionComponent< UsePackageIconType & Omit -> = ({ packageName, version, icons, tryApi, ...euiIconProps }) => { +> = ({ size = 's', packageName, version, icons, tryApi, ...euiIconProps }) => { const iconType = usePackageIconType({ packageName, version, icons, tryApi }); - return ; + return ( + + // this collides with some EuiText (+img) CSS from the EuiIcon component + // which makes the button large, wide, and poorly layed out + // override those styles until the bug is fixed or we find a better approach + style={{ margin: 'unset', width: 'unset' }} + size={size} + type={iconType} + {...euiIconProps} + /> + ); }; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx index 53fab8bda4a8c..26d47cbff5b86 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx @@ -94,7 +94,11 @@ export const StepSelectAgentPolicy: React.FunctionComponent<{ sortOrder: 'asc', full: true, }); - const agentPolicies = useMemo(() => agentPoliciesData?.items || [], [agentPoliciesData?.items]); + const agentPolicies = useMemo( + () => agentPoliciesData?.items.filter((policy) => !policy.is_managed) || [], + [agentPoliciesData?.items] + ); + const agentPoliciesById = useMemo(() => { return agentPolicies.reduce((acc: { [key: string]: GetAgentPoliciesResponseItem }, policy) => { acc[policy.id] = policy; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx index e5ad131bd7e05..d814d2d0646a8 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx @@ -14,7 +14,7 @@ import { useCapabilities, useKibanaVersion } from '../../../../hooks'; import { ContextMenuActions } from '../../../../components'; import { AgentUnenrollAgentModal, - AgentReassignAgentPolicyFlyout, + AgentReassignAgentPolicyModal, AgentUpgradeAgentModal, } from '../../components'; import { useAgentRefresh } from '../hooks'; @@ -45,7 +45,7 @@ export const AgentDetailsActionMenu: React.FunctionComponent<{ <> {isReassignFlyoutOpen && ( - + )} {isUnenrollModalOpen && ( diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.tsx index de27d5fada755..b59ef1f749fb2 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.tsx @@ -22,7 +22,7 @@ import { FormattedMessage, FormattedNumber } from '@kbn/i18n/react'; import { SO_SEARCH_LIMIT } from '../../../../constants'; import type { Agent } from '../../../../types'; import { - AgentReassignAgentPolicyFlyout, + AgentReassignAgentPolicyModal, AgentUnenrollAgentModal, AgentUpgradeAgentModal, } from '../../components'; @@ -161,7 +161,7 @@ export const AgentBulkActions: React.FunctionComponent<{ <> {isReassignFlyoutOpen && ( - { setIsReassignFlyoutOpen(false); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx index 6dd1b8a9693e8..b3c0cf93c88ef 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx @@ -41,7 +41,7 @@ import { AgentPolicySummaryLine, ContextMenuActions } from '../../../components' import { AgentStatusKueryHelper, isAgentUpgradeable } from '../../../services'; import { AGENT_SAVED_OBJECT_TYPE } from '../../../constants'; import { - AgentReassignAgentPolicyFlyout, + AgentReassignAgentPolicyModal, AgentHealth, AgentUnenrollAgentModal, AgentUpgradeAgentModal, @@ -379,7 +379,7 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { return ( - + {agentPolicy && } {showWarning && ( @@ -488,7 +488,7 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { ) : null} {agentToReassign && ( - { setAgentToReassign(undefined); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_enrollment_flyout/steps.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_enrollment_flyout/steps.tsx index 1d5e8cbfc5cd6..faa0461ed4773 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_enrollment_flyout/steps.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_enrollment_flyout/steps.tsx @@ -53,13 +53,16 @@ export const AgentPolicySelectionStep = ({ setSelectedAPIKeyId?: (key: string) => void; setSelectedPolicyId?: (policyId: string) => void; }) => { + const regularAgentPolicies = Array.isArray(agentPolicies) + ? agentPolicies.filter((policy) => policy && !policy.is_managed) + : []; return { title: i18n.translate('xpack.fleet.agentEnrollment.stepChooseAgentPolicyTitle', { defaultMessage: 'Choose an agent policy', }), children: ( void; - agents: Agent[] | string; -} - -export const AgentReassignAgentPolicyFlyout: React.FunctionComponent = ({ - onClose, - agents, -}) => { - const { notifications } = useStartServices(); - const isSingleAgent = Array.isArray(agents) && agents.length === 1; - - const [selectedAgentPolicyId, setSelectedAgentPolicyId] = useState( - isSingleAgent ? (agents[0] as Agent).policy_id : undefined - ); - const agentPoliciesRequest = useGetAgentPolicies({ - page: 1, - perPage: 1000, - }); - // eslint-disable-next-line react-hooks/exhaustive-deps - const agentPolicies = agentPoliciesRequest.data ? agentPoliciesRequest.data.items : []; - useEffect(() => { - if (!selectedAgentPolicyId && agentPolicies[0]) { - setSelectedAgentPolicyId(agentPolicies[0].id); - } - }, [agentPolicies, selectedAgentPolicyId]); - - const [isSubmitting, setIsSubmitting] = useState(false); - async function onSubmit() { - try { - setIsSubmitting(true); - if (!selectedAgentPolicyId) { - throw new Error('No selected agent policy id'); - } - const res = isSingleAgent - ? await sendPutAgentReassign((agents[0] as Agent).id, { - policy_id: selectedAgentPolicyId, - }) - : await sendPostBulkAgentReassign({ - policy_id: selectedAgentPolicyId, - agents: Array.isArray(agents) ? agents.map((agent) => agent.id) : agents, - }); - if (res.error) { - throw res.error; - } - setIsSubmitting(false); - const successMessage = i18n.translate( - 'xpack.fleet.agentReassignPolicy.successSingleNotificationTitle', - { - defaultMessage: 'Agent policy reassigned', - } - ); - notifications.toasts.addSuccess(successMessage); - onClose(); - } catch (error) { - setIsSubmitting(false); - notifications.toasts.addError(error, { - title: 'Unable to reassign agent policy', - }); - } - } - - return ( - - - -

- -

-
- - - - -
- - - - - ({ - value: agentPolicy.id, - text: agentPolicy.name, - }))} - value={selectedAgentPolicyId} - onChange={(e) => setSelectedAgentPolicyId(e.target.value)} - /> - - - - - - {selectedAgentPolicyId && ( - - )} - - - - - - - - - - - - - - - -
- ); -}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_reassign_policy_modal/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_reassign_policy_modal/index.tsx new file mode 100644 index 0000000000000..8ee401d3c4ddf --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_reassign_policy_modal/index.tsx @@ -0,0 +1,159 @@ +/* + * 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, { useState, useEffect, useMemo } from 'react'; +import { i18n } from '@kbn/i18n'; +import { + EuiConfirmModal, + EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + EuiSelect, + EuiFormRow, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; + +import type { Agent } from '../../../../types'; +import { + sendPutAgentReassign, + sendPostBulkAgentReassign, + useStartServices, + useGetAgentPolicies, +} from '../../../../hooks'; +import { AgentPolicyPackageBadges } from '../agent_policy_package_badges'; + +interface Props { + onClose: () => void; + agents: Agent[] | string; +} + +export const AgentReassignAgentPolicyModal: React.FunctionComponent = ({ + onClose, + agents, +}) => { + const { notifications } = useStartServices(); + const isSingleAgent = Array.isArray(agents) && agents.length === 1; + + const [selectedAgentPolicyId, setSelectedAgentPolicyId] = useState( + isSingleAgent ? (agents[0] as Agent).policy_id : undefined + ); + const agentPoliciesRequest = useGetAgentPolicies({ + page: 1, + perPage: 1000, + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + const agentPolicies = agentPoliciesRequest.data ? agentPoliciesRequest.data.items : []; + useEffect(() => { + if (!selectedAgentPolicyId && agentPolicies[0]) { + setSelectedAgentPolicyId(agentPolicies[0].id); + } + }, [agentPolicies, selectedAgentPolicyId]); + + const policySelectOptions = useMemo(() => { + return agentPolicies + .filter((policy) => policy && !policy.is_managed) + .map((agentPolicy) => ({ + value: agentPolicy.id, + text: agentPolicy.name, + })); + }, [agentPolicies]); + + const [isSubmitting, setIsSubmitting] = useState(false); + async function onSubmit() { + try { + setIsSubmitting(true); + if (!selectedAgentPolicyId) { + throw new Error('No selected agent policy id'); + } + const res = isSingleAgent + ? await sendPutAgentReassign((agents[0] as Agent).id, { + policy_id: selectedAgentPolicyId, + }) + : await sendPostBulkAgentReassign({ + policy_id: selectedAgentPolicyId, + agents: Array.isArray(agents) ? agents.map((agent) => agent.id) : agents, + }); + if (res.error) { + throw res.error; + } + setIsSubmitting(false); + const successMessage = i18n.translate( + 'xpack.fleet.agentReassignPolicy.successSingleNotificationTitle', + { + defaultMessage: 'Agent policy reassigned', + } + ); + notifications.toasts.addSuccess(successMessage); + onClose(); + } catch (error) { + setIsSubmitting(false); + notifications.toasts.addError(error, { + title: 'Unable to reassign agent policy', + }); + } + } + + return ( + + } + onCancel={onClose} + onConfirm={onSubmit} + cancelButtonText={ + + } + confirmButtonDisabled={ + isSubmitting || (isSingleAgent && selectedAgentPolicyId === (agents[0] as Agent).policy_id) + } + confirmButtonText={ + + } + buttonColor="danger" + > +

+ +

+ + + + setSelectedAgentPolicyId(e.target.value)} + /> + + + + + + {selectedAgentPolicyId && } +
+ ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/index.tsx index 93425ba10413c..45f09c79d5533 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/index.tsx @@ -6,7 +6,7 @@ */ export * from './loading'; -export * from './agent_reassign_policy_flyout'; +export * from './agent_reassign_policy_modal'; export * from './agent_enrollment_flyout'; export * from './agent_health'; export * from './agent_unenroll_modal';