Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fleet] allow clearing version combo #175322

Merged
merged 3 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,38 @@ describe('AgentUpgradeAgentModal', () => {
});
});

it('should make combo invalid on clearing version', async () => {
const { utils } = renderAgentUpgradeAgentModal({
agents: [{ id: 'agent1', local_metadata: { host: 'abc' } }] as any,
agentCount: 1,
});

await waitFor(() => {
fireEvent.click(utils.getByTestId('comboBoxClearButton'));
const container = utils.getByTestId('agentUpgradeModal.VersionCombobox');
const input = within(container).getByRole<HTMLInputElement>('combobox');
expect(input?.value).toEqual('');
expect(utils.getByText('Version is required')).toBeInTheDocument();
expect(utils.getByTestId('confirmModalConfirmButton')).toBeDisabled();
});
});

it('should make combo invalid on clearing version - bulk action', async () => {
const { utils } = renderAgentUpgradeAgentModal({
agents: '*',
agentCount: 1,
});

await waitFor(() => {
fireEvent.click(utils.getByTestId('comboBoxClearButton'));
const container = utils.getByTestId('agentUpgradeModal.VersionCombobox');
const input = within(container).getByRole<HTMLInputElement>('combobox');
expect(input?.value).toEqual('');
expect(utils.getByText('Version is required')).toBeInTheDocument();
expect(utils.getByTestId('confirmModalConfirmButton')).toBeDisabled();
});
});

it('should display the custom version text input if no versions', async () => {
const { utils } = renderAgentUpgradeAgentModal({
agents: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ export const AgentUpgradeAgentModal: React.FunctionComponent<AgentUpgradeAgentMo
const [updatingQuery, setUpdatingQuery] = useState<Agent[] | string>('');

const QUERY_STUCK_UPDATING = `status:updating AND upgrade_started_at:* AND NOT upgraded_at:* AND upgrade_started_at < now-${AGENT_UPDATING_TIMEOUT_HOURS}h`;
const EMPTY_VALUE = useMemo(() => ({ label: '', value: '' }), []);
const [isInvalid, setIsInvalid] = useState(false);

useEffect(() => {
const getStuckUpdatingAgentCount = async (agentsOrQuery: Agent[] | string) => {
Expand Down Expand Up @@ -179,10 +181,10 @@ export const AgentUpgradeAgentModal: React.FunctionComponent<AgentUpgradeAgentMo
value: option,
}));
if (options.length === 0) {
return [{ label: '', value: '' }];
return [EMPTY_VALUE];
}
return options;
}, [availableVersions, minVersion]);
}, [availableVersions, minVersion, EMPTY_VALUE]);
const noVersions = !availableVersions || versionOptions[0]?.value === '';

const maintenanceOptions: Array<EuiComboBoxOptionOption<number>> = MAINTENANCE_VALUES.map(
Expand Down Expand Up @@ -292,6 +294,7 @@ export const AgentUpgradeAgentModal: React.FunctionComponent<AgentUpgradeAgentMo
value: normalizedSearchValue,
};
setSelectedVersion([newOption]);
setIsInvalid(!normalizedSearchValue);
};

return (
Expand Down Expand Up @@ -343,6 +346,7 @@ export const AgentUpgradeAgentModal: React.FunctionComponent<AgentUpgradeAgentMo
confirmButtonDisabled={
isSubmitting ||
(isUpdating && updatingAgents === 0) ||
!selectedVersion[0].value ||
(isSingleAgent && !isAgentUpgradeableToVersion(agents[0], selectedVersion[0].value))
}
confirmButtonText={
Expand Down Expand Up @@ -378,6 +382,7 @@ export const AgentUpgradeAgentModal: React.FunctionComponent<AgentUpgradeAgentMo
defaultMessage="No newer versions found to upgrade to. You may type in a custom version."
/>
) : isSingleAgent ? (
selectedVersion[0].value &&
!isAgentUpgradeableToVersion(agents[0], selectedVersion[0].value) ? (
<EuiCallOut
data-test-subj="agentUpgradeModal.notUpgradeableCallout"
Expand Down Expand Up @@ -407,10 +412,12 @@ export const AgentUpgradeAgentModal: React.FunctionComponent<AgentUpgradeAgentMo
<p>
<FormattedMessage
id="xpack.fleet.upgradeAgents.upgradeSingleDescription"
defaultMessage="This action will upgrade the agent running on '{hostName}' to version {version}. This action can not be undone. Are you sure you wish to continue?"
defaultMessage="This action will upgrade the agent running on '{hostName}'{version}. This action can not be undone. Are you sure you wish to continue?"
values={{
hostName: ((agents[0] as Agent).local_metadata.host as any).hostname,
version: getVersion(selectedVersion),
version: selectedVersion[0].value
? ' to version ' + getVersion(selectedVersion)
: '',
}}
/>
</p>
Expand All @@ -433,8 +440,10 @@ export const AgentUpgradeAgentModal: React.FunctionComponent<AgentUpgradeAgentMo
) : (
<FormattedMessage
id="xpack.fleet.upgradeAgents.upgradeMultipleDescription"
defaultMessage="This action will upgrade multiple agents to version {version}. This action can not be undone. Are you sure you wish to continue?"
values={{ version: getVersion(selectedVersion) }}
defaultMessage="This action will upgrade multiple agents{version}. This action can not be undone. Are you sure you wish to continue?"
values={{
version: selectedVersion[0].value ? ' to version ' + getVersion(selectedVersion) : '',
}}
/>
)}
</p>
Expand All @@ -443,6 +452,15 @@ export const AgentUpgradeAgentModal: React.FunctionComponent<AgentUpgradeAgentMo
defaultMessage: 'Upgrade version',
})}
fullWidth
isInvalid={isInvalid}
error={
isInvalid ? (
<FormattedMessage
id="xpack.fleet.upgradeAgents.versionRequiredText"
defaultMessage="Version is required"
/>
) : undefined
}
>
{noVersions ? (
<EuiFieldText
Expand All @@ -462,18 +480,22 @@ export const AgentUpgradeAgentModal: React.FunctionComponent<AgentUpgradeAgentMo
fullWidth
singleSelection={{ asPlainText: true }}
options={versionOptions}
isClearable={false}
isClearable={true}
selectedOptions={selectedVersion}
onChange={(selected: Array<EuiComboBoxOptionOption<string>>) => {
if (!selected.length) {
return;
setSelectedVersion([EMPTY_VALUE]);
setIsInvalid(true);
} else {
setSelectedVersion(selected);
setIsInvalid(false);
}
setSelectedVersion(selected);
}}
onCreateOption={
config?.internal?.onlyAllowAgentUpgradeToKnownVersions ? undefined : onCreateOption
}
customOptionText="Use custom agent version {searchValue} (not recommended)"
isInvalid={isInvalid}
/>
)}
</EuiFormRow>
Expand Down
Loading