Skip to content

Commit

Permalink
[Ingest Manager] Handle long agent config & package config names grac…
Browse files Browse the repository at this point in the history
…efully (elastic#72761) (elastic#72918)

* Truncate name in package config table

* Clean up enrollment keys table

* Clean up other tables

* Handle long agent config names with no spaces

* Handle long agent config descriptions without spaces

* Fix types, add tooltips/aria labels

* Fix types again
  • Loading branch information
jen-huang committed Jul 22, 2020
1 parent acd9a89 commit 6c8cc40
Show file tree
Hide file tree
Showing 12 changed files with 116 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,15 @@ export const AgentConfigCopyProvider: React.FunctionComponent<Props> = ({ childr
<EuiOverlayMask>
<EuiConfirmModal
title={
<FormattedMessage
id="xpack.ingestManager.copyAgentConfig.confirmModal.copyConfigTitle"
defaultMessage="Copy '{name}' agent configuration"
values={{
name: agentConfig.name,
}}
/>
<span className="eui-textBreakWord">
<FormattedMessage
id="xpack.ingestManager.copyAgentConfig.confirmModal.copyConfigTitle"
defaultMessage="Copy '{name}' agent configuration"
values={{
name: agentConfig.name,
}}
/>
</span>
}
onCancel={closeModal}
onConfirm={copyAgentConfig}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,17 @@ export const ConfirmDeployConfigModal: React.FunctionComponent<{
},
})}
>
<FormattedMessage
id="xpack.ingestManager.agentConfig.confirmModalCalloutDescription"
defaultMessage="Fleet has detected that the selected agent configuration, {configName}, is already in use by
<div className="eui-textBreakWord">
<FormattedMessage
id="xpack.ingestManager.agentConfig.confirmModalCalloutDescription"
defaultMessage="Fleet has detected that the selected agent configuration, {configName}, is already in use by
some of your agents. As a result of this action, Fleet will deploy updates to all agents
that use this configuration."
values={{
configName: <b>{agentConfig.name}</b>,
}}
/>
values={{
configName: <b>{agentConfig.name}</b>,
}}
/>
</div>
</EuiCallOut>
<EuiSpacer size="l" />
<FormattedMessage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,9 @@ export const CreatePackageConfigPageLayout: React.FunctionComponent<{
defaultMessage="Agent configuration"
/>
</EuiDescriptionListTitle>
<EuiDescriptionListDescription>{agentConfig?.name || '-'}</EuiDescriptionListDescription>
<EuiDescriptionListDescription className="eui-textBreakWord">
{agentConfig?.name || '-'}
</EuiDescriptionListDescription>
</EuiDescriptionList>
) : undefined;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ export const PackageConfigsTable: React.FunctionComponent<Props> = ({
defaultMessage: 'Name',
}
),
render: (value: string) => (
<span className="eui-textTruncate" title={value}>
{value}
</span>
),
},
{
field: 'description',
Expand All @@ -113,7 +118,11 @@ export const PackageConfigsTable: React.FunctionComponent<Props> = ({
defaultMessage: 'Description',
}
),
truncateText: true,
render: (value: string) => (
<span className="eui-textTruncate" title={value}>
{value}
</span>
),
},
{
field: 'packageTitle',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const AgentConfigDetailsPage: React.FunctionComponent = () => {
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem>
<EuiText>
<EuiText className="eui-textBreakWord">
<h1>
{(agentConfig && agentConfig.name) || (
<FormattedMessage
Expand All @@ -92,7 +92,7 @@ export const AgentConfigDetailsPage: React.FunctionComponent = () => {
{agentConfig && agentConfig.description ? (
<EuiFlexItem>
<EuiSpacer size="s" />
<EuiText color="subdued" size="s">
<EuiText color="subdued" size="s" className="eui-textBreakWord">
{agentConfig.description}
</EuiText>
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,9 @@ export const AgentConfigListPage: React.FunctionComponent<{}> = () => {
defaultMessage: 'Description',
}),
width: '35%',
truncateText: true,
render: (description: AgentConfig['description']) => (
<EuiTextColor color="subdued" className="eui-textTruncate">
{description}
render: (value: string) => (
<EuiTextColor color="subdued" className="eui-textTruncate" title={value}>
{value}
</EuiTextColor>
),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,23 +75,20 @@ export const DataStreamListPage: React.FunctionComponent<{}> = () => {
field: 'dataset',
sortable: true,
width: '25%',
truncateText: true,
name: i18n.translate('xpack.ingestManager.dataStreamList.datasetColumnTitle', {
defaultMessage: 'Dataset',
}),
},
{
field: 'type',
sortable: true,
truncateText: true,
name: i18n.translate('xpack.ingestManager.dataStreamList.typeColumnTitle', {
defaultMessage: 'Type',
}),
},
{
field: 'namespace',
sortable: true,
truncateText: true,
name: i18n.translate('xpack.ingestManager.dataStreamList.namespaceColumnTitle', {
defaultMessage: 'Namespace',
}),
Expand All @@ -102,7 +99,6 @@ export const DataStreamListPage: React.FunctionComponent<{}> = () => {
{
field: 'package',
sortable: true,
truncateText: true,
name: i18n.translate('xpack.ingestManager.dataStreamList.integrationColumnTitle', {
defaultMessage: 'Integration',
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ export const AgentDetailsContent: React.FunctionComponent<{
defaultMessage: 'Agent configuration',
}),
description: agentConfig ? (
<EuiLink href={getHref('configuration_details', { configId: agent.config_id! })}>
<EuiLink
href={getHref('configuration_details', { configId: agent.config_id! })}
className="eui-textBreakWord"
>
{agentConfig.name || agent.config_id}
</EuiLink>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,11 @@ export const AgentEventsTable: React.FunctionComponent<{ agent: Agent }> = ({ ag
name: i18n.translate('xpack.ingestManager.agentEventsList.messageColumnTitle', {
defaultMessage: 'Message',
}),
render: (message: string) => <EuiText size="xs">{message}</EuiText>,
truncateText: true,
render: (value: string) => (
<EuiText size="xs" className="eui-textTruncate">
{value}
</EuiText>
),
},
{
align: RIGHT_ALIGNMENT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ export const AgentDetailsPage: React.FunctionComponent = () => {
) : agentConfigData?.item ? (
<EuiLink
href={getHref('configuration_details', { configId: agentData.item.config_id! })}
className="eui-textBreakWord"
>
{agentConfigData.item.name || agentData.item.config_id}
</EuiLink>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage, FormattedRelative } from '@kbn/i18n/react';
import { CSSProperties } from 'styled-components';
import { AgentEnrollmentFlyout } from '../components';
import { Agent, AgentConfig } from '../../../types';
import {
Expand All @@ -40,11 +39,6 @@ import { AgentStatusKueryHelper } from '../../../services';
import { AGENT_SAVED_OBJECT_TYPE } from '../../../constants';
import { AgentReassignConfigFlyout, AgentHealth, AgentUnenrollProvider } from '../components';

const NO_WRAP_TRUNCATE_STYLE: CSSProperties = Object.freeze({
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
});
const REFRESH_INTERVAL_MS = 5000;

const statusFilters = [
Expand Down Expand Up @@ -279,10 +273,10 @@ export const AgentListPage: React.FunctionComponent<{}> = () => {
const configName = agentConfigs.find((p) => p.id === configId)?.name;
return (
<EuiFlexGroup gutterSize="s" alignItems="center" style={{ minWidth: 0 }}>
<EuiFlexItem grow={false} style={NO_WRAP_TRUNCATE_STYLE}>
<EuiFlexItem grow={false} className="eui-textTruncate">
<EuiLink
href={getHref('configuration_details', { configId })}
style={NO_WRAP_TRUNCATE_STYLE}
className="eui-textTruncate"
title={configName || configId}
>
{configName || configId}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@

import { i18n } from '@kbn/i18n';
import React, { useState } from 'react';
import { CSSProperties } from 'styled-components';
import {
EuiSpacer,
EuiBasicTable,
EuiFlexGroup,
EuiFlexItem,
EuiButton,
EuiButtonEmpty,
EuiButtonIcon,
EuiToolTip,
EuiIcon,
EuiText,
HorizontalAlignment,
} from '@elastic/eui';
import { FormattedMessage, FormattedDate } from '@kbn/i18n/react';
import { ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE } from '../../../constants';
Expand All @@ -33,12 +34,6 @@ import { SearchBar } from '../../../components/search_bar';
import { NewEnrollmentTokenFlyout } from './components/new_enrollment_key_flyout';
import { ConfirmEnrollmentTokenDelete } from './components/confirm_delete_modal';

const NO_WRAP_TRUNCATE_STYLE: CSSProperties = Object.freeze({
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
});

const ApiKeyField: React.FunctionComponent<{ apiKeyId: string }> = ({ apiKeyId }) => {
const { notifications } = useCore();
const [state, setState] = useState<'VISIBLE' | 'HIDDEN' | 'LOADING'>('HIDDEN');
Expand Down Expand Up @@ -66,24 +61,42 @@ const ApiKeyField: React.FunctionComponent<{ apiKeyId: string }> = ({ apiKeyId }
};

return (
<EuiFlexGroup alignItems="flexStart" gutterSize="none">
<EuiFlexItem grow={false}>
{state === 'VISIBLE' ? (
<EuiText color="subdued" size="xs">
{key}
</EuiText>
) : (
<EuiText color="subdued">•••••••••••••••••••••</EuiText>
)}
<EuiFlexGroup alignItems="center" gutterSize="xs">
<EuiFlexItem>
<EuiText color="subdued" size="xs">
{state === 'VISIBLE'
? key
: '•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••'}
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButtonEmpty
size="xs"
color="text"
isLoading={state === 'LOADING'}
onClick={toggleKey}
iconType={state === 'VISIBLE' ? 'eyeClosed' : 'eye'}
/>
<EuiToolTip
content={
state === 'VISIBLE'
? i18n.translate('xpack.ingestManager.enrollmentTokensList.hideTokenButtonLabel', {
defaultMessage: 'Hide token',
})
: i18n.translate('xpack.ingestManager.enrollmentTokensList.showTokenButtonLabel', {
defaultMessage: 'Show token',
})
}
>
<EuiButtonIcon
aria-label={
state === 'VISIBLE'
? i18n.translate('xpack.ingestManager.enrollmentTokensList.hideTokenButtonLabel', {
defaultMessage: 'Hide token',
})
: i18n.translate('xpack.ingestManager.enrollmentTokensList.showTokenButtonLabel', {
defaultMessage: 'Show token',
})
}
color="text"
isDisabled={state === 'LOADING'}
onClick={toggleKey}
iconType={state === 'VISIBLE' ? 'eyeClosed' : 'eye'}
/>
</EuiToolTip>
</EuiFlexItem>
</EuiFlexGroup>
);
Expand Down Expand Up @@ -120,7 +133,23 @@ const DeleteButton: React.FunctionComponent<{ apiKey: EnrollmentAPIKey; refresh:
onConfirm={onConfirm}
/>
)}
<EuiButtonEmpty onClick={() => setState('CONFIRM_VISIBLE')} iconType="trash" color="danger" />
<EuiToolTip
content={i18n.translate('xpack.ingestManager.enrollmentTokensList.revokeTokenButtonLabel', {
defaultMessage: 'Revoke token',
})}
>
<EuiButtonIcon
aria-label={i18n.translate(
'xpack.ingestManager.enrollmentTokensList.revokeTokenButtonLabel',
{
defaultMessage: 'Revoke token',
}
)}
onClick={() => setState('CONFIRM_VISIBLE')}
iconType="trash"
color="danger"
/>
</EuiToolTip>
</>
);
};
Expand Down Expand Up @@ -152,15 +181,11 @@ export const EnrollmentTokenListPage: React.FunctionComponent<{}> = () => {
name: i18n.translate('xpack.ingestManager.enrollmentTokensList.nameTitle', {
defaultMessage: 'Name',
}),
truncateText: true,
textOnly: true,
render: (name: string) => {
return (
<EuiText size="s" style={NO_WRAP_TRUNCATE_STYLE} title={name}>
{name}
</EuiText>
);
},
render: (value: string) => (
<span className="eui-textTruncate" title={value}>
{value}
</span>
),
},
{
field: 'id',
Expand All @@ -179,7 +204,12 @@ export const EnrollmentTokenListPage: React.FunctionComponent<{}> = () => {
}),
render: (configId: string) => {
const config = agentConfigs.find((c) => c.id === configId);
return <>{config ? config.name : configId}</>;
const value = config ? config.name : configId;
return (
<span className="eui-textTruncate" title={value}>
{value}
</span>
);
},
},
{
Expand All @@ -200,12 +230,9 @@ export const EnrollmentTokenListPage: React.FunctionComponent<{}> = () => {
defaultMessage: 'Active',
}),
width: '70px',
align: 'center' as HorizontalAlignment,
render: (active: boolean) => {
return (
<EuiText textAlign="center">
<EuiIcon size="m" color={active ? 'success' : 'danger'} type="dot" />
</EuiText>
);
return <EuiIcon size="m" color={active ? 'success' : 'danger'} type="dot" />;
},
},
{
Expand Down Expand Up @@ -242,7 +269,7 @@ export const EnrollmentTokenListPage: React.FunctionComponent<{}> = () => {
/>
</EuiText>
<EuiSpacer size="m" />
<EuiFlexGroup alignItems={'center'}>
<EuiFlexGroup alignItems="center">
<EuiFlexItem>
<SearchBar
value={search}
Expand Down

0 comments on commit 6c8cc40

Please sign in to comment.