Skip to content

Commit

Permalink
[UII] Remove action links and buttons when secrets field is disabled (#…
Browse files Browse the repository at this point in the history
…188252)

## Summary

Resolves #187642 

This PR removes action links and buttons to replace and convert secrets
fields if the field itself is disabled, for cases like the user not
having write permissions:

<img width="730" alt="image"
src="https://github.com/user-attachments/assets/957ad858-74bf-4f28-a212-148253e4ca0f">

<img width="716" alt="image"
src="https://github.com/user-attachments/assets/d70f7946-8b62-4e13-9d16-98ddac26b826">

Also applies sentence casing to `Service token` label.

### Checklist

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
  • Loading branch information
jen-huang authored Jul 12, 2024
1 parent fdd67f7 commit 4c0db61
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ queue:

cy.contains('Name is required');
cy.contains('URL is required');
cy.contains('Service Token is required');
cy.contains('Service token is required');
shouldDisplayError(SETTINGS_OUTPUTS.NAME_INPUT);
shouldDisplayError('serviceTokenSecretInput');
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const kafkaSectionsLabels = [
'Broker settings',
];

const remoteEsOutputLabels = ['Hosts', 'Service Token'];
const remoteEsOutputLabels = ['Hosts', 'Service token'];

describe('EditOutputFlyout', () => {
const mockStartServices = (isServerlessEnabled?: boolean) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export const OutputFormRemoteEsSection: React.FunctionComponent<Props> = (props)
label={
<FormattedMessage
id="xpack.fleet.settings.editOutputFlyout.serviceTokenLabel"
defaultMessage="Service Token"
defaultMessage="Service token"
/>
}
{...inputs.serviceTokenInput.formRowProps}
Expand All @@ -105,7 +105,7 @@ export const OutputFormRemoteEsSection: React.FunctionComponent<Props> = (props)
<SecretFormRow
fullWidth
title={i18n.translate('xpack.fleet.settings.editOutputFlyout.serviceTokenLabel', {
defaultMessage: 'Service Token',
defaultMessage: 'Service token',
})}
{...inputs.serviceTokenSecretInput.formRowProps}
cancelEdit={inputs.serviceTokenSecretInput.cancelEdit}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import React from 'react';
import { fireEvent } from '@testing-library/react';
import { renderReactTestingLibraryWithI18n } from '@kbn/test-jest-helpers';

import { SecretFormRow } from './output_form_secret_form_row';

describe('SecretFormRow', () => {
Expand Down Expand Up @@ -42,8 +43,8 @@ describe('SecretFormRow', () => {
expect(queryByText(initialValue)).not.toBeInTheDocument();
});

it('should not enable the replace button if the row is disabled', () => {
const { getByText } = renderReactTestingLibraryWithI18n(
it('should not enable action links if the row is disabled', () => {
const { getByText, queryByText } = renderReactTestingLibraryWithI18n(
<SecretFormRow
title={title}
initialValue={initialValue}
Expand All @@ -57,7 +58,10 @@ describe('SecretFormRow', () => {
</SecretFormRow>
);

expect(getByText('Replace Test Secret').closest('button')).toBeDisabled();
expect(getByText('The saved Test Secret is hidden.')).toBeInTheDocument();
expect(queryByText('Replace Test Secret')).not.toBeInTheDocument();
expect(queryByText('Click to use secret storage instead')).not.toBeInTheDocument();
expect(queryByText('Click to use plain text storage instead')).not.toBeInTheDocument();
});

it('should call the cancelEdit function when the cancel button is clicked', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,32 +55,45 @@ export const SecretFormRow: React.FC<{
const [editMode, setEditMode] = useState(isConvertedToSecret || !initialValue);
const valueHiddenPanel = (
<EuiPanel color="subdued" borderRadius="none" hasShadow={false}>
<EuiText size="s" color="subdued">
<FormattedMessage
id="xpack.fleet.outputForm.secretValueHiddenMessage"
defaultMessage="The saved {varName} is hidden. You can only replace the {varName}."
values={{
varName: title,
}}
/>
</EuiText>
<EuiSpacer size="s" />
<EuiButtonEmpty
disabled={disabled}
onClick={() => setEditMode(true)}
color="primary"
iconType="refresh"
iconSide="left"
size="xs"
>
<FormattedMessage
id="xpack.fleet.outputForm.editSecretValue"
defaultMessage="Replace {varName}"
values={{
varName: title,
}}
/>
</EuiButtonEmpty>
{disabled ? (
<EuiText size="s" color="subdued">
<FormattedMessage
id="xpack.fleet.outputForm.secretValueHiddenAndDisabledMessage"
defaultMessage="The saved {varName} is hidden."
values={{
varName: title,
}}
/>
</EuiText>
) : (
<>
<EuiText size="s" color="subdued">
<FormattedMessage
id="xpack.fleet.outputForm.secretValueHiddenMessage"
defaultMessage="The saved {varName} is hidden. You can only replace the {varName}."
values={{
varName: title,
}}
/>
</EuiText>
<EuiSpacer size="s" />
<EuiButtonEmpty
onClick={() => setEditMode(true)}
color="primary"
iconType="refresh"
iconSide="left"
size="xs"
>
<FormattedMessage
id="xpack.fleet.outputForm.editSecretValue"
defaultMessage="Replace {varName}"
values={{
varName: title,
}}
/>
</EuiButtonEmpty>
</>
)}
</EuiPanel>
);

Expand Down Expand Up @@ -134,6 +147,7 @@ export const SecretFormRow: React.FC<{
);

const helpText = useMemo(() => {
if (disabled) return null;
if (isConvertedToSecret)
return (
<EuiCallOut size="s" color="warning">
Expand Down Expand Up @@ -172,9 +186,9 @@ export const SecretFormRow: React.FC<{
/>
);
return undefined;
}, [initialValue, isConvertedToSecret, onToggleSecretStorage]);
}, [disabled, initialValue, isConvertedToSecret, onToggleSecretStorage]);

const plainTextHelp = (
const plainTextHelp = disabled ? null : (
<FormattedMessage
id="xpack.fleet.settings.editOutputFlyout.secretInputCalloutTitle"
defaultMessage="This field should be stored as a secret, currently it is set to be stored as plain text. {enableSecretLink}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ export function validateServiceToken(value: string) {
if (!value || value === '') {
return [
i18n.translate('xpack.fleet.settings.outputForm.serviceTokenRequiredErrorMessage', {
defaultMessage: 'Service Token is required',
defaultMessage: 'Service token is required',
}),
];
}
Expand Down

0 comments on commit 4c0db61

Please sign in to comment.