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

[ResponseOps][Cases]Add instructions of how to create a connector in the create case form #197041

Merged
Show file tree
Hide file tree
Changes from 11 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 @@ -21,12 +21,20 @@ import {
import { ConnectorsDropdown } from './connectors_dropdown';
import { connectors, actionTypes } from './__mock__';
import { ConnectorTypes } from '../../../common/types/domain';
import userEvent from '@testing-library/user-event';
import { useApplicationCapabilities } from '../../common/lib/kibana';

const useApplicationCapabilitiesMock = useApplicationCapabilities as jest.Mocked<
typeof useApplicationCapabilities
>;
jest.mock('../../common/lib/kibana');

describe('Connectors', () => {
let wrapper: ReactWrapper;
let appMockRender: AppMockRenderer;
const onChangeConnector = jest.fn();
const handleShowEditFlyout = jest.fn();
const onAddNewConnector = jest.fn();

const props: Props = {
actionTypes,
Expand All @@ -38,6 +46,7 @@ describe('Connectors', () => {
onChangeConnector,
selectedConnector: { id: 'none', type: ConnectorTypes.none },
updateConnectorDisabled: false,
onAddNewConnector,
};

beforeAll(() => {
Expand Down Expand Up @@ -104,12 +113,16 @@ describe('Connectors', () => {
});

it('shows the add connector button', () => {
wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click');
wrapper.update();
appMockRender.render(<Connectors {...props} />);

expect(
wrapper.find('button[data-test-subj="dropdown-connector-add-connector"]').exists()
).toBeTruthy();
expect(screen.getByTestId('add-new-connector')).toBeInTheDocument();
});

it('shows the add connector flyout when the button is clicked', async () => {
appMockRender.render(<Connectors {...props} />);

await userEvent.click(screen.getByTestId('add-new-connector'));
expect(onAddNewConnector).toHaveBeenCalled();
});

it('the text of the update button is shown correctly', () => {
Expand Down Expand Up @@ -156,16 +169,14 @@ describe('Connectors', () => {
});

it('shows the actions permission message if the user does not have read access to actions', async () => {
appMockRender.coreStart.application.capabilities = {
...appMockRender.coreStart.application.capabilities,
actions: { save: false, show: false },
};
useApplicationCapabilitiesMock().actions = { crud: false, read: false };

appMockRender.render(<Connectors {...props} />);

const result = appMockRender.render(<Connectors {...props} />);
expect(
result.getByTestId('configure-case-connector-permissions-error-msg')
await screen.findByTestId('configure-case-connector-permissions-error-msg')
).toBeInTheDocument();
expect(result.queryByTestId('case-connectors-dropdown')).toBe(null);
expect(screen.queryByTestId('case-connectors-dropdown')).not.toBeInTheDocument();
});

it('shows the actions permission message if the user does not have access to case connector', async () => {
Expand All @@ -177,4 +188,12 @@ describe('Connectors', () => {
).toBeInTheDocument();
expect(result.queryByTestId('case-connectors-dropdown')).toBe(null);
});

it('it should hide the "Add Connector" button when the user lacks the capability to add a new connector', async () => {
useApplicationCapabilitiesMock().actions = { crud: false, read: true };

appMockRender.render(<Connectors {...props} />);

expect(screen.queryByTestId('add-new-connector')).not.toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ import {
EuiFlexItem,
EuiLink,
EuiText,
EuiButtonEmpty,
} from '@elastic/eui';

import { css } from '@emotion/react';

import { ConnectorsDropdown } from './connectors_dropdown';
import * as i18n from './translations';

Expand All @@ -39,6 +38,7 @@ export interface Props {
onChangeConnector: (id: string) => void;
selectedConnector: { id: string; type: ConnectorTypes };
updateConnectorDisabled: boolean;
onAddNewConnector: () => void;
}
const ConnectorsComponent: React.FC<Props> = ({
actionTypes,
Expand All @@ -50,8 +50,10 @@ const ConnectorsComponent: React.FC<Props> = ({
onChangeConnector,
selectedConnector,
updateConnectorDisabled,
onAddNewConnector,
}) => {
const { actions } = useApplicationCapabilities();
const canSave = actions.crud;
const connector = useMemo(
() => connectors.find((c) => c.id === selectedConnector.id),
[connectors, selectedConnector.id]
Expand Down Expand Up @@ -95,13 +97,19 @@ const ConnectorsComponent: React.FC<Props> = ({
>
<EuiFormRow
fullWidth
css={css`
label {
width: 100%;
}
`}
label={dropDownLabel}
data-test-subj="case-connectors-form-row"
labelAppend={
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should hide the label if the user does not have access to create connectors. You can check this by doing

const { actions } = useApplicationCapabilities();
const canSave = actions.crud;

labelAppend={canSave ? <EuiButtonEmpty // rest of code /> : undefined}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, thanks!

canSave ? (
<EuiButtonEmpty
size="xs"
data-test-subj="add-new-connector"
onClick={onAddNewConnector}
>
{i18n.ADD_CONNECTOR}
</EuiButtonEmpty>
) : null
}
>
<EuiFlexGroup direction="column">
<EuiFlexItem grow={false}>
Expand All @@ -113,7 +121,6 @@ const ConnectorsComponent: React.FC<Props> = ({
isLoading={isLoading}
onChange={onChangeConnector}
data-test-subj="case-connectors-dropdown"
appendAddConnectorButton={true}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Now that the appendAddConnectorButton is not used anymore what about removing the functionality (appendAddConnectorButton) from the ConnectorsDropdown component?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, thanks!

/>
) : (
<EuiText data-test-subj="configure-case-connector-permissions-error-msg" size="s">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@ import type { Props } from './connectors_dropdown';
import { ConnectorsDropdown } from './connectors_dropdown';
import { TestProviders } from '../../common/mock';
import { connectors } from './__mock__';
import userEvent from '@testing-library/user-event';
import { useApplicationCapabilities } from '../../common/lib/kibana';

const useApplicationCapabilitiesMock = useApplicationCapabilities as jest.Mocked<
typeof useApplicationCapabilities
>;
jest.mock('../../common/lib/kibana');

describe('ConnectorsDropdown', () => {
let wrapper: ReactWrapper;
Expand Down Expand Up @@ -388,23 +381,4 @@ describe('ConnectorsDropdown', () => {
);
expect(tooltips[0]).toBeInTheDocument();
});

test('it should hide the "Add New Connector" button when the user lacks the capability to add a new connector', async () => {
const selectedConnector = 'none';
useApplicationCapabilitiesMock().actions = { crud: false, read: true };
render(
<ConnectorsDropdown
appendAddConnectorButton={true}
connectors={[]}
selectedConnector={selectedConnector}
disabled={false}
isLoading={false}
onChange={() => {}}
/>,
{ wrapper: ({ children }) => <TestProviders>{children}</TestProviders> }
);

await userEvent.click(screen.getByTestId('dropdown-connectors'));
expect(screen.queryByTestId('dropdown-connector-add-connector')).not.toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/

import React, { Suspense, useMemo } from 'react';
import type { EuiThemeComputed } from '@elastic/eui';
import {
EuiFlexGroup,
EuiFlexItem,
Expand All @@ -20,7 +19,7 @@ import { css } from '@emotion/react';

import type { ActionConnector } from '../../containers/configure/types';
import * as i18n from './translations';
import { useApplicationCapabilities, useKibana } from '../../common/lib/kibana';
import { useKibana } from '../../common/lib/kibana';
import { getConnectorIcon, isDeprecatedConnector } from '../utils';

export interface Props {
Expand All @@ -29,7 +28,6 @@ export interface Props {
isLoading: boolean;
onChange: (id: string) => void;
selectedConnector: string;
appendAddConnectorButton?: boolean;
}

const suspendedComponentWithProps = (ComponentToSuspend: React.ComponentType) => {
Expand Down Expand Up @@ -65,37 +63,14 @@ const noConnectorOption = {
'data-test-subj': 'dropdown-connector-no-connector',
};

const addNewConnector = (euiTheme: EuiThemeComputed<{}>) => ({
value: 'add-connector',
inputDisplay: (
<span
css={css`
font-size: ${euiTheme.font.scale.xs};
font-weight: ${euiTheme.font.weight.medium};
line-height: ${euiTheme.size.l};

&:hover {
text-decoration: underline;
}
`}
>
{i18n.ADD_NEW_CONNECTOR}
</span>
),
'data-test-subj': 'dropdown-connector-add-connector',
});

const ConnectorsDropdownComponent: React.FC<Props> = ({
connectors,
disabled,
isLoading,
onChange,
selectedConnector,
appendAddConnectorButton = false,
}) => {
const { triggersActionsUi } = useKibana().services;
const { actions } = useApplicationCapabilities();
const canSave = actions.crud;
const { euiTheme } = useEuiTheme();
const connectorsAsOptions = useMemo(() => {
const connectorsFormatted = connectors.reduce(
Expand Down Expand Up @@ -152,10 +127,6 @@ const ConnectorsDropdownComponent: React.FC<Props> = ({
[noConnectorOption]
);

if (appendAddConnectorButton && canSave) {
return [...connectorsFormatted, addNewConnector(euiTheme)];
}

return connectorsFormatted;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [connectors]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -565,8 +565,7 @@ describe('ConfigureCases', () => {
wrappingComponent: TestProviders as ComponentType<React.PropsWithChildren<{}>>,
});

wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click');
wrapper.find('button[data-test-subj="dropdown-connector-add-connector"]').simulate('click');
wrapper.find('button[data-test-subj="add-new-connector"]').simulate('click');

await waitFor(() => {
wrapper.update();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ export const ConfigureCases: React.FC = React.memo(() => {
[]
);

const onAddNewConnector = useCallback(() => {
setFlyOutVisibility({ type: 'addConnector', visible: true });
}, []);

const onChangeConnector = useCallback(
(id: string) => {
if (id === 'add-connector') {
Expand Down Expand Up @@ -577,6 +581,7 @@ export const ConfigureCases: React.FC = React.memo(() => {
onChangeConnector={onChangeConnector}
selectedConnector={connector}
updateConnectorDisabled={updateConnectorDisabled || !permissions.update}
onAddNewConnector={onAddNewConnector}
/>
</div>
<EuiSpacer size="xl" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ export const ADD_NEW_CONNECTOR = i18n.translate('xpack.cases.configureCases.addN
defaultMessage: 'Add new connector',
});

export const ADD_CONNECTOR = i18n.translate('xpack.cases.configureCases.addConnector', {
defaultMessage: 'Add connector',
});

export const CASE_CLOSURE_OPTIONS_TITLE = i18n.translate(
'xpack.cases.configureCases.caseClosureOptionsTitle',
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,17 @@ import { css } from '@emotion/react';

import type { FieldHook } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib';
import { getFieldValidityAndErrorMessage } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib';
import { i18n } from '@kbn/i18n';
import type { ActionConnector } from '../../../common/types/domain';
import { ConnectorsDropdown } from '../configure_cases/connectors_dropdown';

const ADD_CONNECTOR_HELPER_TEXT = i18n.translate(
'xpack.cases.connectorSelector.addConnectorHelperText',
{
defaultMessage: 'Go to Cases > Settings to add an external incident management system',
}
);

interface ConnectorSelectorProps {
connectors: ActionConnector[];
dataTestSubj: string;
Expand Down Expand Up @@ -60,7 +68,7 @@ export const ConnectorSelector = ({
describedByIds={idAria ? [idAria] : undefined}
error={errorMessage}
fullWidth
helpText={field.helpText}
helpText={ADD_CONNECTOR_HELPER_TEXT}
isInvalid={isInvalid}
label={field.label}
labelAppend={field.labelAppend}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
});

it('opens and closes the connectors flyout correctly', async () => {
await common.clickAndValidate('dropdown-connectors', 'dropdown-connector-add-connector');
await common.clickAndValidate('dropdown-connector-add-connector', 'euiFlyoutCloseButton');
await common.clickAndValidate('add-new-connector', 'euiFlyoutCloseButton');
await testSubjects.click('euiFlyoutCloseButton');
expect(await testSubjects.exists('euiFlyoutCloseButton')).to.be(false);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
});

it('opens and closes the connectors flyout correctly', async () => {
await common.clickAndValidate('dropdown-connectors', 'dropdown-connector-add-connector');
await common.clickAndValidate('dropdown-connector-add-connector', 'euiFlyoutCloseButton');
await common.clickAndValidate('add-new-connector', 'euiFlyoutCloseButton');
await testSubjects.click('euiFlyoutCloseButton');
expect(await testSubjects.exists('euiFlyoutCloseButton')).to.be(false);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
});

it('opens and closes the connectors flyout correctly', async () => {
await common.clickAndValidate('dropdown-connectors', 'dropdown-connector-add-connector');
await common.clickAndValidate('dropdown-connector-add-connector', 'euiFlyoutCloseButton');
await common.clickAndValidate('add-new-connector', 'euiFlyoutCloseButton');
await testSubjects.click('euiFlyoutCloseButton');
expect(await testSubjects.exists('euiFlyoutCloseButton')).to.be(false);
});
Expand Down