Skip to content

Commit

Permalink
[Cases] Display required badge in custom field configuration. (elasti…
Browse files Browse the repository at this point in the history
…c#171975)

Fixes elastic#167767

## Summary

I added information about whether the custom field is required or not.

Additionally, I followed @mdefazio 's comment and changed how we display
these to use an`EuiBadge` instead. The color is custom.

<img width="1207" alt="Screenshot 2023-11-27 at 11 57 52"
src="https://github.com/elastic/kibana/assets/1533137/4c491293-1ccf-4377-843f-55fef45fc9b3">
  • Loading branch information
adcoelho authored Nov 27, 2023
1 parent 8d7816c commit 5f5c92a
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,28 +37,43 @@ describe('CustomFieldsList', () => {
it('shows CustomFieldsList correctly', async () => {
appMockRender.render(<CustomFieldsList {...props} />);

expect(screen.getByTestId('custom-fields-list')).toBeInTheDocument();
expect(await screen.findByTestId('custom-fields-list')).toBeInTheDocument();

for (const field of customFieldsConfigurationMock) {
expect(screen.getByTestId(`custom-field-${field.key}-${field.type}`)).toBeInTheDocument();
}
expect(
await screen.findByTestId(
`custom-field-${customFieldsConfigurationMock[0].key}-${customFieldsConfigurationMock[0].type}`
)
).toBeInTheDocument();
expect(await screen.findByText('Text')).toBeInTheDocument();
expect(await screen.findByText('Required')).toBeInTheDocument();
expect(
await screen.findByTestId(
`custom-field-${customFieldsConfigurationMock[1].key}-${customFieldsConfigurationMock[1].type}`
)
).toBeInTheDocument();
expect(await screen.findByText('Toggle')).toBeInTheDocument();
});

it('shows single CustomFieldsList correctly', async () => {
appMockRender.render(
<CustomFieldsList {...{ ...props, customFields: [customFieldsConfigurationMock[0]] }} />
);

const list = screen.getByTestId('custom-fields-list');
const list = await screen.findByTestId('custom-fields-list');

expect(list).toBeInTheDocument();
expect(
screen.getByTestId(
await screen.findByTestId(
`custom-field-${customFieldsConfigurationMock[0].key}-${customFieldsConfigurationMock[0].type}`
)
).toBeInTheDocument();
expect(await screen.findByText('Text')).toBeInTheDocument();
expect(await screen.findByText('Required')).toBeInTheDocument();
expect(
await within(list).findByTestId(`${customFieldsConfigurationMock[0].key}-custom-field-edit`)
).toBeInTheDocument();
expect(
within(list).getByTestId(`${customFieldsConfigurationMock[0].key}-custom-field-delete`)
await within(list).findByTestId(`${customFieldsConfigurationMock[0].key}-custom-field-delete`)
).toBeInTheDocument();
});

Expand All @@ -76,10 +91,12 @@ describe('CustomFieldsList', () => {
it('shows confirmation modal when deleting a field ', async () => {
appMockRender.render(<CustomFieldsList {...props} />);

const list = screen.getByTestId('custom-fields-list');
const list = await screen.findByTestId('custom-fields-list');

userEvent.click(
within(list).getByTestId(`${customFieldsConfigurationMock[0].key}-custom-field-delete`)
await within(list).findByTestId(
`${customFieldsConfigurationMock[0].key}-custom-field-delete`
)
);

expect(await screen.findByTestId('confirm-delete-custom-field-modal')).toBeInTheDocument();
Expand All @@ -88,15 +105,17 @@ describe('CustomFieldsList', () => {
it('calls onDeleteCustomField when confirm', async () => {
appMockRender.render(<CustomFieldsList {...props} />);

const list = screen.getByTestId('custom-fields-list');
const list = await screen.findByTestId('custom-fields-list');

userEvent.click(
within(list).getByTestId(`${customFieldsConfigurationMock[0].key}-custom-field-delete`)
await within(list).findByTestId(
`${customFieldsConfigurationMock[0].key}-custom-field-delete`
)
);

expect(await screen.findByTestId('confirm-delete-custom-field-modal')).toBeInTheDocument();

userEvent.click(screen.getByText('Delete'));
userEvent.click(await screen.findByText('Delete'));

await waitFor(() => {
expect(screen.queryByTestId('confirm-delete-custom-field-modal')).not.toBeInTheDocument();
Expand All @@ -109,15 +128,17 @@ describe('CustomFieldsList', () => {
it('does not call onDeleteCustomField when cancel', async () => {
appMockRender.render(<CustomFieldsList {...props} />);

const list = screen.getByTestId('custom-fields-list');
const list = await screen.findByTestId('custom-fields-list');

userEvent.click(
within(list).getByTestId(`${customFieldsConfigurationMock[0].key}-custom-field-delete`)
await within(list).findByTestId(
`${customFieldsConfigurationMock[0].key}-custom-field-delete`
)
);

expect(await screen.findByTestId('confirm-delete-custom-field-modal')).toBeInTheDocument();

userEvent.click(screen.getByText('Cancel'));
userEvent.click(await screen.findByText('Cancel'));

await waitFor(() => {
expect(screen.queryByTestId('confirm-delete-custom-field-modal')).not.toBeInTheDocument();
Expand All @@ -134,10 +155,10 @@ describe('CustomFieldsList', () => {
it('calls onEditCustomField correctly', async () => {
appMockRender.render(<CustomFieldsList {...props} />);

const list = screen.getByTestId('custom-fields-list');
const list = await screen.findByTestId('custom-fields-list');

userEvent.click(
within(list).getByTestId(`${customFieldsConfigurationMock[0].key}-custom-field-edit`)
await within(list).findByTestId(`${customFieldsConfigurationMock[0].key}-custom-field-edit`)
);

await waitFor(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import {
EuiSpacer,
EuiText,
EuiButtonIcon,
useEuiTheme,
EuiBadge,
} from '@elastic/eui';
import * as i18n from '../translations';

import type { CustomFieldTypes, CustomFieldsConfiguration } from '../../../../common/types/domain';
import { builderMap } from '../builder';
Expand All @@ -28,6 +31,7 @@ export interface Props {
const CustomFieldsListComponent: React.FC<Props> = (props) => {
const { customFields, onDeleteCustomField, onEditCustomField } = props;
const [selectedItem, setSelectedItem] = useState<CustomFieldsConfiguration[number] | null>(null);
const { euiTheme } = useEuiTheme();

const renderTypeLabel = (type?: CustomFieldTypes) => {
const createdBuilder = type && builderMap[type];
Expand Down Expand Up @@ -69,7 +73,12 @@ const CustomFieldsListComponent: React.FC<Props> = (props) => {
<h4>{customField.label}</h4>
</EuiText>
</EuiFlexItem>
<EuiText color="subdued">{renderTypeLabel(customField.type)}</EuiText>
<EuiBadge color={euiTheme.colors.body}>
{renderTypeLabel(customField.type)}
</EuiBadge>
{customField.required && (
<EuiBadge color={euiTheme.colors.body}>{i18n.REQUIRED}</EuiBadge>
)}
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem grow={false}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ export const FIELD_OPTION_REQUIRED = i18n.translate(
}
);

export const REQUIRED = i18n.translate('xpack.cases.customFields.required', {
defaultMessage: 'Required',
});

export const REQUIRED_FIELD = (fieldName: string): string =>
i18n.translate('xpack.cases.customFields.requiredField', {
values: { fieldName },
Expand Down

0 comments on commit 5f5c92a

Please sign in to comment.