Skip to content

Commit

Permalink
Use <AgentPolicySummaryLine /> for consistent name+icon lockup (#97377)…
Browse files Browse the repository at this point in the history
… (#97441)

## Summary

From design ticket elastic/observability-design#32
> any ... place we display a link to the hosted agent policy, show an icon with hover tooltip:

This PR closes 1B + 1C from #91906 & two other places which followed the same pattern.

Factored out some repeated code at each call site into a `<AgentPolicySummaryLine />` component


<details><summary>Screenshots</summary>
<h3>Agent Policy List View</h3>
<img width="1103" alt="Screen Shot 2021-04-16 at 1 01 55 PM" src="https://user-images.githubusercontent.com/57655/115059112-18a99180-9eb4-11eb-9035-36a8e9db1f9d.png">

<h3>Agent List View</h3>
<img width="1185" alt="Screen Shot 2021-04-16 at 12 38 40 PM" src="https://user-images.githubusercontent.com/57655/115058885-bea8cc00-9eb3-11eb-8529-6f185fcac7d2.png">


<h3>Packaged Policy List View</h3>
<img width="1251" alt="Screen Shot 2021-04-16 at 10 23 49 AM" src="https://user-images.githubusercontent.com/57655/115058880-be103580-9eb3-11eb-8060-c501663af556.png">

<h3>Agent Policy Detail View</h3>
<img width="1145" alt="Screen Shot 2021-04-16 at 12 21 42 PM" src="https://user-images.githubusercontent.com/57655/115058883-bea8cc00-9eb3-11eb-9970-462ff4600fa4.png">



</details>

### Checklist

Delete any items that are not applicable to this PR.

- [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>

Co-authored-by: John Schulz <john.schulz@elastic.co>
  • Loading branch information
kibanamachine and John Schulz authored Apr 19, 2021
1 parent a5f590d commit ca84475
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,54 @@
* 2.0.
*/

import { EuiFlexGroup, EuiFlexItem, EuiLink, EuiText } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiIconTip, EuiLink, EuiText } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import type { CSSProperties } from 'react';
import React, { memo } from 'react';
import type { EuiLinkProps } from '@elastic/eui/src/components/link/link';

import type { AgentPolicy } from '../../../../common/types';
import { useLink } from '../hooks';
const MIN_WIDTH: CSSProperties = { minWidth: 0 };
const NO_WRAP_WHITE_SPACE: CSSProperties = { whiteSpace: 'nowrap' };

export type LinkAndRevisionProps = EuiLinkProps & {
revision?: string | number;
};

/**
* Components shows a link for a given value along with a revision number to its right. The display
* value is truncated if it is longer than the width of where it is displayed, while the revision
* always remain visible
*/
export const LinkAndRevision = memo<LinkAndRevisionProps>(
({ revision, className, ...euiLinkProps }) => {
return (
<EuiFlexGroup gutterSize="s" alignItems="baseline" style={MIN_WIDTH} responsive={false}>
<EuiFlexItem grow={false} className="eui-textTruncate">
<EuiLink className={`eui-textTruncate ${className ?? ''}`} {...euiLinkProps} />
export const AgentPolicySummaryLine = memo<{ policy: AgentPolicy }>(({ policy }) => {
const { getHref } = useLink();
const { name, id, revision, is_managed: isManaged } = policy;
return (
<EuiFlexGroup gutterSize="s" alignItems="baseline" style={MIN_WIDTH} responsive={false}>
<EuiFlexItem grow={false} className="eui-textTruncate">
<EuiLink
className={`eui-textTruncate`}
href={getHref('policy_details', { policyId: id })}
title={name || id}
>
{name || id}
</EuiLink>
</EuiFlexItem>
{isManaged && (
<EuiIconTip
title="Hosted agent policy"
content={i18n.translate('xpack.fleet.agentPolicySummaryLine.hostedPolicyTooltip', {
defaultMessage:
'This policy is managed outside of Fleet. Most actions related to this policy are unavailable.',
})}
type="lock"
size="m"
color="subdued"
/>
)}
{revision && (
<EuiFlexItem grow={true}>
<EuiText color="subdued" size="xs" style={NO_WRAP_WHITE_SPACE}>
<FormattedMessage
id="xpack.fleet.agentPolicySummaryLine.revisionNumber"
defaultMessage="rev. {revNumber}"
values={{ revNumber: revision }}
/>
</EuiText>
</EuiFlexItem>
{revision && (
<EuiFlexItem grow={true}>
<EuiText color="subdued" size="xs" style={NO_WRAP_WHITE_SPACE}>
<FormattedMessage
id="xpack.fleet.policyNameLink.revisionNumber"
defaultMessage="rev. {revNumber}"
values={{ revNumber: revision }}
/>
</EuiText>
</EuiFlexItem>
)}
</EuiFlexGroup>
);
}
);
)}
</EuiFlexGroup>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import {
useUrlParams,
useBreadcrumbs,
} from '../../../hooks';
import { LinkAndRevision, SearchBar } from '../../../components';
import { AgentPolicySummaryLine, SearchBar } from '../../../components';
import { LinkedAgentCount, AgentPolicyActionMenu } from '../components';

import { CreateAgentPolicyFlyout } from './components';
Expand Down Expand Up @@ -74,7 +74,7 @@ const AgentPolicyListPageLayout: React.FunctionComponent = ({ children }) => (

export const AgentPolicyListPage: React.FunctionComponent<{}> = () => {
useBreadcrumbs('policies_list');
const { getHref, getPath } = useLink();
const { getPath } = useLink();
const hasWriteCapabilites = useCapabilities().write;
const {
agents: { enabled: isFleetEnabled },
Expand Down Expand Up @@ -132,13 +132,7 @@ export const AgentPolicyListPage: React.FunctionComponent<{}> = () => {
}),
width: '20%',
render: (name: string, agentPolicy: AgentPolicy) => (
<LinkAndRevision
href={getHref('policy_details', { policyId: agentPolicy.id })}
title={name || agentPolicy.id}
revision={agentPolicy.revision}
>
{name || agentPolicy.id}
</LinkAndRevision>
<AgentPolicySummaryLine policy={agentPolicy} />
),
},
{
Expand Down Expand Up @@ -205,7 +199,7 @@ export const AgentPolicyListPage: React.FunctionComponent<{}> = () => {
}

return cols;
}, [getHref, isFleetEnabled, resendRequest]);
}, [isFleetEnabled, resendRequest]);

const createAgentPolicyButton = useMemo(
() => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';

import type { Agent, AgentPolicy } from '../../../../../types';
import { useKibanaVersion, useLink } from '../../../../../hooks';
import { useKibanaVersion } from '../../../../../hooks';
import { isAgentUpgradeable } from '../../../../../services';
import { AgentPolicyPackageBadges } from '../../../components/agent_policy_package_badges';
import { LinkAndRevision } from '../../../../../components';
import { AgentPolicySummaryLine } from '../../../../../components';

// Allows child text to be truncated
const FlexItemWithMinWidth = styled(EuiFlexItem)`
Expand All @@ -35,7 +35,6 @@ export const AgentDetailsOverviewSection: React.FunctionComponent<{
agent: Agent;
agentPolicy?: AgentPolicy;
}> = memo(({ agent, agentPolicy }) => {
const { getHref } = useLink();
const kibanaVersion = useKibanaVersion();
return (
<EuiPanel>
Expand All @@ -52,13 +51,7 @@ export const AgentDetailsOverviewSection: React.FunctionComponent<{
defaultMessage: 'Agent policy',
}),
description: agentPolicy ? (
<LinkAndRevision
href={getHref('policy_details', { policyId: agentPolicy.id })}
title={agentPolicy.name || agent.policy_id}
revision={agent.policy_revision || undefined}
>
{agentPolicy.name || agentPolicy.id}
</LinkAndRevision>
<AgentPolicySummaryLine policy={agentPolicy} />
) : (
agent.policy_id || '-'
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
useKibanaVersion,
useStartServices,
} from '../../../hooks';
import { ContextMenuActions } from '../../../components';
import { AgentPolicySummaryLine, ContextMenuActions } from '../../../components';
import { AgentStatusKueryHelper, isAgentUpgradeable } from '../../../services';
import { AGENT_SAVED_OBJECT_TYPE } from '../../../constants';
import {
Expand Down Expand Up @@ -374,48 +374,24 @@ export const AgentListPage: React.FunctionComponent<{}> = () => {
defaultMessage: 'Agent policy',
}),
render: (policyId: string, agent: Agent) => {
const policyName = agentPoliciesIndexedById[policyId]?.name;
const agentPolicy = agentPoliciesIndexedById[policyId];
const showWarning = agent.policy_revision && agentPolicy?.revision > agent.policy_revision;

return (
<EuiFlexGroup gutterSize="s" alignItems="center" style={{ minWidth: 0 }}>
<EuiFlexItem grow={false} className="eui-textTruncate">
<EuiLink
href={getHref('policy_details', { policyId })}
className="eui-textTruncate"
title={policyName || policyId}
>
{policyName || policyId}
</EuiLink>
</EuiFlexItem>
{agent.policy_revision && (
<AgentPolicySummaryLine policy={agentPolicy} />
{showWarning && (
<EuiFlexItem grow={false}>
<EuiText color="default" size="xs" className="eui-textNoWrap">
<EuiText color="subdued" size="xs" className="eui-textNoWrap">
<EuiIcon size="m" type="alert" color="warning" />
&nbsp;
<FormattedMessage
id="xpack.fleet.agentList.revisionNumber"
defaultMessage="rev. {revNumber}"
values={{ revNumber: agent.policy_revision }}
id="xpack.fleet.agentList.outOfDateLabel"
defaultMessage="Out-of-date"
/>
</EuiText>
</EuiFlexItem>
)}
{agent.policy_id &&
agent.policy_revision &&
agentPoliciesIndexedById[agent.policy_id] &&
agentPoliciesIndexedById[agent.policy_id].revision > agent.policy_revision && (
<EuiFlexItem grow={false}>
<EuiText color="subdued" size="xs" className="eui-textNoWrap">
<EuiIcon size="m" type="alert" color="warning" />
&nbsp;
{true && (
<>
<FormattedMessage
id="xpack.fleet.agentList.outOfDateLabel"
defaultMessage="Out-of-date"
/>
</>
)}
</EuiText>
</EuiFlexItem>
)}
</EuiFlexGroup>
);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* 2.0.
*/

import type { ReactNode } from 'react';
import React, { memo, useCallback, useMemo } from 'react';
import { Redirect } from 'react-router-dom';
import type { CriteriaWithPagination, EuiTableFieldDataColumnType } from '@elastic/eui';
Expand All @@ -16,8 +15,7 @@ import { FormattedRelative, FormattedMessage } from '@kbn/i18n/react';
import { InstallStatus } from '../../../../../types';
import { useLink, useUrlPagination } from '../../../../../hooks';
import { PACKAGE_POLICY_SAVED_OBJECT_TYPE } from '../../../../../constants';
import type { LinkAndRevisionProps } from '../../../../../components';
import { LinkAndRevision } from '../../../../../components';
import { AgentPolicySummaryLine } from '../../../../../components';
import { LinkedAgentCount } from '../../../../../components/linked_agent_count';
import { useGetPackageInstallStatus } from '../../../hooks';

Expand All @@ -42,27 +40,6 @@ const IntegrationDetailsLink = memo<{
</EuiLink>
);
});

const AgentPolicyDetailLink = memo<{
agentPolicyId: string;
revision: LinkAndRevisionProps['revision'];
children: ReactNode;
}>(({ agentPolicyId, revision, children }) => {
const { getHref } = useLink();

return (
<LinkAndRevision
className="eui-textTruncate"
revision={revision}
href={getHref('policy_details', {
policyId: agentPolicyId,
})}
>
{children}
</LinkAndRevision>
);
});

interface PackagePoliciesPanelProps {
name: string;
version: string;
Expand Down Expand Up @@ -112,11 +89,7 @@ export const PackagePoliciesPage = ({ name, version }: PackagePoliciesPanelProps
}),
truncateText: true,
render(id, { agentPolicy }) {
return (
<AgentPolicyDetailLink agentPolicyId={id} revision={agentPolicy.revision}>
{agentPolicy.name ?? id}
</AgentPolicyDetailLink>
);
return <AgentPolicySummaryLine policy={agentPolicy} />;
},
},
{
Expand Down
2 changes: 0 additions & 2 deletions x-pack/plugins/translations/translations/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -8235,7 +8235,6 @@
"xpack.fleet.agentList.policyColumnTitle": "エージェントポリシー",
"xpack.fleet.agentList.policyFilterText": "エージェントポリシー",
"xpack.fleet.agentList.reassignActionText": "新しいポリシーに割り当てる",
"xpack.fleet.agentList.revisionNumber": "rev. {revNumber}",
"xpack.fleet.agentList.showUpgradeableFilterLabel": "アップグレードが利用可能です",
"xpack.fleet.agentList.statusColumnTitle": "ステータス",
"xpack.fleet.agentList.statusFilterText": "ステータス",
Expand Down Expand Up @@ -8653,7 +8652,6 @@
"xpack.fleet.policyForm.generalSettingsGroupDescription": "エージェントポリシーの名前と説明を選択してください。",
"xpack.fleet.policyForm.generalSettingsGroupTitle": "一般設定",
"xpack.fleet.policyForm.unableToDeleteDefaultPolicyText": "デフォルトポリシーは削除できません",
"xpack.fleet.policyNameLink.revisionNumber": "rev. {revNumber}",
"xpack.fleet.securityRequiredErrorMessage": "Fleet を使用するには、Kibana と Elasticsearch でセキュリティを有効にする必要があります。",
"xpack.fleet.securityRequiredErrorTitle": "セキュリティが有効ではありません",
"xpack.fleet.settings.additionalYamlConfig": "Elasticsearch出力構成",
Expand Down
3 changes: 1 addition & 2 deletions x-pack/plugins/translations/translations/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -8309,7 +8309,6 @@
"xpack.fleet.agentList.policyColumnTitle": "代理策略",
"xpack.fleet.agentList.policyFilterText": "代理策略",
"xpack.fleet.agentList.reassignActionText": "分配到新策略",
"xpack.fleet.agentList.revisionNumber": "修订版 {revNumber}",
"xpack.fleet.agentList.showUpgradeableFilterLabel": "升级可用",
"xpack.fleet.agentList.statusColumnTitle": "状态",
"xpack.fleet.agentList.statusFilterText": "状态",
Expand Down Expand Up @@ -8737,7 +8736,7 @@
"xpack.fleet.policyForm.generalSettingsGroupDescription": "为您的代理策略选择名称和描述。",
"xpack.fleet.policyForm.generalSettingsGroupTitle": "常规设置",
"xpack.fleet.policyForm.unableToDeleteDefaultPolicyText": "默认策略无法删除",
"xpack.fleet.policyNameLink.revisionNumber": "修订版 {revNumber}",
"xpack.fleet.agentPolicySummaryLine.revisionNumber": "修订版 {revNumber}",
"xpack.fleet.securityRequiredErrorMessage": "必须在 Kibana 和 Elasticsearch 启用安全性,才能使用 Fleet。",
"xpack.fleet.securityRequiredErrorTitle": "安全性未启用",
"xpack.fleet.settings.additionalYamlConfig": "Elasticsearch 输出配置",
Expand Down

0 comments on commit ca84475

Please sign in to comment.