[Ingest Manager] Convert select agent config step to use combo box (#73172)
* Initial pass at using combo box instead of selectable for agent configs * Hide agent count messaging if fleet isn't set up * Fix types * Fix i18n * Fix i18n again * Add comment explaining styling Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
5af2c1080a
commit
82d7e7db69
|
@ -3,17 +3,19 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import React, { useEffect, useState, Fragment } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import {
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiSelectable,
|
||||
EuiSpacer,
|
||||
EuiComboBox,
|
||||
EuiComboBoxOptionOption,
|
||||
EuiTextColor,
|
||||
EuiPortal,
|
||||
EuiButtonEmpty,
|
||||
EuiFormRow,
|
||||
EuiLink,
|
||||
} from '@elastic/eui';
|
||||
import { Error } from '../../../components';
|
||||
import { AgentConfig, PackageInfo, GetAgentConfigsResponseItem } from '../../../types';
|
||||
|
@ -23,9 +25,30 @@ import {
|
|||
useGetAgentConfigs,
|
||||
sendGetOneAgentConfig,
|
||||
useCapabilities,
|
||||
useFleetStatus,
|
||||
} from '../../../hooks';
|
||||
import { CreateAgentConfigFlyout } from '../list_page/components';
|
||||
|
||||
const AgentConfigWrapper = styled(EuiFormRow)`
|
||||
.euiFormRow__label {
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
// Custom styling for drop down list items due to:
|
||||
// 1) the max-width and overflow properties is added to prevent long config
|
||||
// names/descriptions from overflowing the flex items
|
||||
// 2) max-width is built from the grow property on the flex items because the value
|
||||
// changes based on if Fleet is enabled/setup or not
|
||||
const AgentConfigNameColumn = styled(EuiFlexItem)`
|
||||
max-width: ${(props) => `${((props.grow as number) / 9) * 100}%`};
|
||||
overflow: hidden;
|
||||
`;
|
||||
const AgentConfigDescriptionColumn = styled(EuiFlexItem)`
|
||||
max-width: ${(props) => `${((props.grow as number) / 9) * 100}%`};
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
export const StepSelectConfig: React.FunctionComponent<{
|
||||
pkgkey: string;
|
||||
updatePackageInfo: (packageInfo: PackageInfo | undefined) => void;
|
||||
|
@ -33,6 +56,8 @@ export const StepSelectConfig: React.FunctionComponent<{
|
|||
updateAgentConfig: (config: AgentConfig | undefined) => void;
|
||||
setIsLoadingSecondStep: (isLoading: boolean) => void;
|
||||
}> = ({ pkgkey, updatePackageInfo, agentConfig, updateAgentConfig, setIsLoadingSecondStep }) => {
|
||||
const { isReady: isFleetReady } = useFleetStatus();
|
||||
|
||||
// Selected config state
|
||||
const [selectedConfigId, setSelectedConfigId] = useState<string | undefined>(
|
||||
agentConfig ? agentConfig.id : undefined
|
||||
|
@ -106,6 +131,40 @@ export const StepSelectConfig: React.FunctionComponent<{
|
|||
}
|
||||
}, [selectedConfigId, agentConfig, updateAgentConfig, setIsLoadingSecondStep]);
|
||||
|
||||
const agentConfigOptions: Array<EuiComboBoxOptionOption<string>> = packageInfoData
|
||||
? agentConfigs.map((agentConf) => {
|
||||
const alreadyHasLimitedPackage =
|
||||
(isLimitedPackage &&
|
||||
doesAgentConfigAlreadyIncludePackage(agentConf, packageInfoData.response.name)) ||
|
||||
false;
|
||||
return {
|
||||
label: agentConf.name,
|
||||
value: agentConf.id,
|
||||
disabled: alreadyHasLimitedPackage,
|
||||
'data-test-subj': 'agentConfigItem',
|
||||
};
|
||||
})
|
||||
: [];
|
||||
|
||||
const selectedConfigOption = agentConfigOptions.find(
|
||||
(option) => option.value === selectedConfigId
|
||||
);
|
||||
|
||||
// Try to select default agent config
|
||||
useEffect(() => {
|
||||
if (!selectedConfigId && agentConfigs.length && agentConfigOptions.length) {
|
||||
const defaultAgentConfig = agentConfigs.find((config) => config.is_default);
|
||||
if (defaultAgentConfig) {
|
||||
const defaultAgentConfigOption = agentConfigOptions.find(
|
||||
(option) => option.value === defaultAgentConfig.id
|
||||
);
|
||||
if (defaultAgentConfigOption && !defaultAgentConfigOption.disabled) {
|
||||
setSelectedConfigId(defaultAgentConfig.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [agentConfigs, agentConfigOptions, selectedConfigId]);
|
||||
|
||||
// Display package error if there is one
|
||||
if (packageInfoError) {
|
||||
return (
|
||||
|
@ -154,77 +213,95 @@ export const StepSelectConfig: React.FunctionComponent<{
|
|||
) : null}
|
||||
<EuiFlexGroup direction="column" gutterSize="m">
|
||||
<EuiFlexItem>
|
||||
<EuiSelectable
|
||||
searchable
|
||||
allowExclusions={false}
|
||||
singleSelection={true}
|
||||
isLoading={isAgentConfigsLoading || isPackageInfoLoading}
|
||||
options={agentConfigs.map((agentConf) => {
|
||||
const alreadyHasLimitedPackage =
|
||||
(isLimitedPackage &&
|
||||
packageInfoData &&
|
||||
doesAgentConfigAlreadyIncludePackage(agentConf, packageInfoData.response.name)) ||
|
||||
false;
|
||||
return {
|
||||
label: agentConf.name,
|
||||
key: agentConf.id,
|
||||
checked: selectedConfigId === agentConf.id ? 'on' : undefined,
|
||||
disabled: alreadyHasLimitedPackage,
|
||||
'data-test-subj': 'agentConfigItem',
|
||||
};
|
||||
})}
|
||||
renderOption={(option) => (
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={false}>{option.label}</EuiFlexItem>
|
||||
<AgentConfigWrapper
|
||||
fullWidth={true}
|
||||
label={
|
||||
<EuiFlexGroup justifyContent="spaceBetween">
|
||||
<EuiFlexItem>
|
||||
<EuiTextColor color="subdued">
|
||||
{agentConfigsById[option.key!].description}
|
||||
</EuiTextColor>
|
||||
<FormattedMessage
|
||||
id="xpack.ingestManager.createPackageConfig.StepSelectConfig.agentConfigLabel"
|
||||
defaultMessage="Agent configuration"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTextColor color="subdued">
|
||||
<FormattedMessage
|
||||
id="xpack.ingestManager.createPackageConfig.StepSelectConfig.agentConfigAgentsCountText"
|
||||
defaultMessage="{count, plural, one {# agent} other {# agents}}"
|
||||
values={{
|
||||
count: agentConfigsById[option.key!].agents || 0,
|
||||
}}
|
||||
/>
|
||||
</EuiTextColor>
|
||||
<div>
|
||||
<EuiLink
|
||||
disabled={!hasWriteCapabilites}
|
||||
onClick={() => setIsCreateAgentConfigFlyoutOpen(true)}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.ingestManager.createPackageConfig.StepSelectConfig.addButton"
|
||||
defaultMessage="Create agent configuration"
|
||||
/>
|
||||
</EuiLink>
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
)}
|
||||
listProps={{
|
||||
bordered: true,
|
||||
}}
|
||||
searchProps={{
|
||||
placeholder: i18n.translate(
|
||||
'xpack.ingestManager.createPackageConfig.StepSelectConfig.filterAgentConfigsInputPlaceholder',
|
||||
{
|
||||
defaultMessage: 'Search for agent configurations',
|
||||
}
|
||||
),
|
||||
}}
|
||||
height={180}
|
||||
onChange={(options) => {
|
||||
const selectedOption = options.find((option) => option.checked === 'on');
|
||||
if (selectedOption) {
|
||||
if (selectedOption.key !== selectedConfigId) {
|
||||
setSelectedConfigId(selectedOption.key);
|
||||
}
|
||||
} else {
|
||||
setSelectedConfigId(undefined);
|
||||
}
|
||||
}}
|
||||
}
|
||||
helpText={
|
||||
isFleetReady && selectedConfigId ? (
|
||||
<FormattedMessage
|
||||
id="xpack.ingestManager.createPackageConfig.StepSelectConfig.agentConfigAgentsDescriptionText"
|
||||
defaultMessage="{count, plural, one {# agent} other {# agents}} are enrolled with the selected agent configuration."
|
||||
values={{
|
||||
count: agentConfigsById[selectedConfigId].agents || 0,
|
||||
}}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
>
|
||||
{(list, search) => (
|
||||
<Fragment>
|
||||
{search}
|
||||
<EuiSpacer size="m" />
|
||||
{list}
|
||||
</Fragment>
|
||||
)}
|
||||
</EuiSelectable>
|
||||
<EuiComboBox
|
||||
placeholder={i18n.translate(
|
||||
'xpack.ingestManager.createPackageConfig.StepSelectConfig.agentConfigPlaceholderText',
|
||||
{
|
||||
defaultMessage: 'Select an agent configuration to add this integration to',
|
||||
}
|
||||
)}
|
||||
singleSelection={{ asPlainText: true }}
|
||||
isClearable={false}
|
||||
fullWidth={true}
|
||||
isLoading={isAgentConfigsLoading || isPackageInfoLoading}
|
||||
options={agentConfigOptions}
|
||||
renderOption={(option: EuiComboBoxOptionOption<string>) => {
|
||||
return (
|
||||
<EuiFlexGroup>
|
||||
<AgentConfigNameColumn grow={2}>
|
||||
<span className="eui-textTruncate">{option.label}</span>
|
||||
</AgentConfigNameColumn>
|
||||
<AgentConfigDescriptionColumn grow={isFleetReady ? 5 : 7}>
|
||||
<EuiTextColor className="eui-textTruncate" color="subdued">
|
||||
{agentConfigsById[option.value!].description}
|
||||
</EuiTextColor>
|
||||
</AgentConfigDescriptionColumn>
|
||||
{isFleetReady ? (
|
||||
<EuiFlexItem grow={2} className="eui-textRight">
|
||||
<EuiTextColor color="subdued">
|
||||
<FormattedMessage
|
||||
id="xpack.ingestManager.createPackageConfig.StepSelectConfig.agentConfigAgentsCountText"
|
||||
defaultMessage="{count, plural, one {# agent} other {# agents}} enrolled"
|
||||
values={{
|
||||
count: agentConfigsById[option.value!].agents || 0,
|
||||
}}
|
||||
/>
|
||||
</EuiTextColor>
|
||||
</EuiFlexItem>
|
||||
) : null}
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
}}
|
||||
selectedOptions={selectedConfigOption ? [selectedConfigOption] : []}
|
||||
onChange={(options) => {
|
||||
const selectedOption = options[0] || undefined;
|
||||
if (selectedOption) {
|
||||
if (selectedOption.value !== selectedConfigId) {
|
||||
setSelectedConfigId(selectedOption.value);
|
||||
}
|
||||
} else {
|
||||
setSelectedConfigId(undefined);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</AgentConfigWrapper>
|
||||
</EuiFlexItem>
|
||||
{/* Display selected agent config error if there is one */}
|
||||
{selectedConfigError ? (
|
||||
|
@ -240,22 +317,6 @@ export const StepSelectConfig: React.FunctionComponent<{
|
|||
/>
|
||||
</EuiFlexItem>
|
||||
) : null}
|
||||
<EuiFlexItem>
|
||||
<div>
|
||||
<EuiButtonEmpty
|
||||
iconType="plusInCircle"
|
||||
isDisabled={!hasWriteCapabilites}
|
||||
onClick={() => setIsCreateAgentConfigFlyoutOpen(true)}
|
||||
flush="left"
|
||||
size="s"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.ingestManager.createPackageConfig.StepSelectConfig.addButton"
|
||||
defaultMessage="New agent configuration"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -160,7 +160,7 @@ export const CreateAgentConfigFlyout: React.FunctionComponent<Props> = ({
|
|||
);
|
||||
|
||||
return (
|
||||
<FlyoutWithHigherZIndex onClose={onClose} size="l" maxWidth={400} {...restOfProps}>
|
||||
<FlyoutWithHigherZIndex onClose={() => onClose()} size="l" maxWidth={400} {...restOfProps}>
|
||||
{header}
|
||||
{body}
|
||||
{footer}
|
||||
|
|
|
@ -8108,7 +8108,6 @@
|
|||
"xpack.ingestManager.createPackageConfig.StepSelectConfig.errorLoadingAgentConfigsTitle": "エージェント構成の読み込みエラー",
|
||||
"xpack.ingestManager.createPackageConfig.StepSelectConfig.errorLoadingPackageTitle": "パッケージ情報の読み込みエラー",
|
||||
"xpack.ingestManager.createPackageConfig.StepSelectConfig.errorLoadingSelectedAgentConfigTitle": "選択したエージェント構成の読み込みエラー",
|
||||
"xpack.ingestManager.createPackageConfig.StepSelectConfig.filterAgentConfigsInputPlaceholder": "エージェント構成の検索",
|
||||
"xpack.ingestManager.createPackageConfig.stepSelectPackage.errorLoadingConfigTitle": "エージェント構成情報の読み込みエラー",
|
||||
"xpack.ingestManager.createPackageConfig.stepSelectPackage.errorLoadingPackagesTitle": "統合の読み込みエラー",
|
||||
"xpack.ingestManager.createPackageConfig.stepSelectPackage.errorLoadingSelectedPackageTitle": "選択した統合の読み込みエラー",
|
||||
|
|
|
@ -8113,7 +8113,6 @@
|
|||
"xpack.ingestManager.createPackageConfig.StepSelectConfig.errorLoadingAgentConfigsTitle": "加载代理配置时出错",
|
||||
"xpack.ingestManager.createPackageConfig.StepSelectConfig.errorLoadingPackageTitle": "加载软件包信息时出错",
|
||||
"xpack.ingestManager.createPackageConfig.StepSelectConfig.errorLoadingSelectedAgentConfigTitle": "加载选定代理配置时出错",
|
||||
"xpack.ingestManager.createPackageConfig.StepSelectConfig.filterAgentConfigsInputPlaceholder": "搜索代理配置",
|
||||
"xpack.ingestManager.createPackageConfig.stepSelectPackage.errorLoadingConfigTitle": "加载代理配置信息时出错",
|
||||
"xpack.ingestManager.createPackageConfig.stepSelectPackage.errorLoadingPackagesTitle": "加载集成时出错",
|
||||
"xpack.ingestManager.createPackageConfig.stepSelectPackage.errorLoadingSelectedPackageTitle": "加载选定集成时出错",
|
||||
|
|
Loading…
Reference in a new issue