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

[Security Solution] Connector selector onboarding #203742

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
595480f
WIP: connector selector onboarding
agusruidiazgd Dec 11, 2024
60d1ab0
more changes
agusruidiazgd Dec 11, 2024
b506cd7
some improvements with react use query
agusruidiazgd Dec 12, 2024
1aa83f0
Merge branch 'main' into feat/ia-connector-design-update
agusruidiazgd Dec 12, 2024
f9eddb7
integrate the selectedConnectorID
agusruidiazgd Dec 12, 2024
b441541
more improvements and code polishing
agusruidiazgd Dec 12, 2024
f0903d8
cleaning code
agusruidiazgd Dec 12, 2024
424983f
adapt connector cards
agusruidiazgd Dec 12, 2024
314e3be
improve connector selector
agusruidiazgd Dec 13, 2024
fb52880
improve connector selector
agusruidiazgd Dec 13, 2024
25ee868
remove unnecesary code
agusruidiazgd Dec 13, 2024
efeb930
Merge branch 'main' into feat/ia-connector-design-update
agusruidiazgd Dec 15, 2024
ee9f7ab
update new architecture
agusruidiazgd Dec 15, 2024
2ca78e1
Merge branch 'main' into feat/ia-connector-design-update
agusruidiazgd Dec 16, 2024
aff016e
Merge branch 'main' into feat/ia-connector-design-update
elasticmachine Dec 16, 2024
3be14f6
fix build
agusruidiazgd Dec 16, 2024
6027730
[CI] Auto-commit changed files from 'node scripts/generate codeowners'
kibanamachine Dec 16, 2024
4771b47
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Dec 16, 2024
7d28c25
fix jest config for connectors package
agusruidiazgd Dec 16, 2024
3935d09
Merge branch 'main' into feat/ia-connector-design-update
elasticmachine Dec 16, 2024
d9cca6d
Merge branch 'main' into feat/ia-connector-design-update
agusruidiazgd Dec 16, 2024
ce78120
Merge branch 'main' into feat/ia-connector-design-update
agusruidiazgd Jan 17, 2025
b39ed61
improvements
agusruidiazgd Jan 20, 2025
cb3c7a9
[CI] Auto-commit changed files from 'node scripts/build_plugin_list_d…
kibanamachine Jan 20, 2025
c62d8c4
[CI] Auto-commit changed files from 'node scripts/styled_components_m…
kibanamachine Jan 20, 2025
e3dd9cd
Merge branch 'main' into feat/ia-connector-design-update
elasticmachine Jan 20, 2025
9e21092
more improvements
agusruidiazgd Jan 20, 2025
5ed138e
fix check types
agusruidiazgd Jan 21, 2025
3049eaa
Merge branch 'main' into feat/ia-connector-design-update
agusruidiazgd Jan 22, 2025
36816e5
Merge branch 'main' into feat/ia-connector-design-update
agusruidiazgd Jan 22, 2025
1ceb51a
Merge branch 'main' into feat/ia-connector-design-update
agusruidiazgd Jan 23, 2025
fec7eee
remove old location file
agusruidiazgd Jan 23, 2025
f306731
fix comments
agusruidiazgd Jan 24, 2025
3b450b0
remove duplicated config
agusruidiazgd Jan 24, 2025
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
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,7 @@ x-pack/solutions/search/plugins/search_playground @elastic/search-kibana
x-pack/solutions/search/plugins/search_solution/search_navigation @elastic/search-kibana
x-pack/solutions/search/plugins/search_synonyms @elastic/search-kibana
x-pack/solutions/search/plugins/serverless_search @elastic/search-kibana
x-pack/solutions/security/packages/connectors @elastic/security-threat-hunting-explore
x-pack/solutions/security/packages/data_table @elastic/security-threat-hunting-investigations
x-pack/solutions/security/packages/data-stream-adapter @elastic/security-threat-hunting
x-pack/solutions/security/packages/distribution_bar @elastic/kibana-cloud-security-posture
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,7 @@
"@kbn/security-plugin-types-public": "link:x-pack/platform/packages/shared/security/plugin_types_public",
"@kbn/security-plugin-types-server": "link:x-pack/platform/packages/shared/security/plugin_types_server",
"@kbn/security-role-management-model": "link:x-pack/platform/packages/private/security/role_management_model",
"@kbn/security-solution-connectors": "link:x-pack/solutions/security/packages/connectors",
"@kbn/security-solution-distribution-bar": "link:x-pack/solutions/security/packages/distribution_bar",
"@kbn/security-solution-ess": "link:x-pack/solutions/security/plugins/security_solution_ess",
"@kbn/security-solution-features": "link:x-pack/solutions/security/packages/features",
Expand Down
2 changes: 2 additions & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -1632,6 +1632,8 @@
"@kbn/security-plugin-types-server/*": ["x-pack/platform/packages/shared/security/plugin_types_server/*"],
"@kbn/security-role-management-model": ["x-pack/platform/packages/private/security/role_management_model"],
"@kbn/security-role-management-model/*": ["x-pack/platform/packages/private/security/role_management_model/*"],
"@kbn/security-solution-connectors": ["x-pack/solutions/security/packages/connectors"],
"@kbn/security-solution-connectors/*": ["x-pack/solutions/security/packages/connectors/*"],
"@kbn/security-solution-distribution-bar": ["x-pack/solutions/security/packages/distribution_bar"],
"@kbn/security-solution-distribution-bar/*": ["x-pack/solutions/security/packages/distribution_bar/*"],
"@kbn/security-solution-ess": ["x-pack/solutions/security/plugins/security_solution_ess"],
Expand Down
9 changes: 9 additions & 0 deletions x-pack/solutions/security/packages/connectors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

export { ConnectorSelector } from './src/connector_selector';
export type { ConnectorSelectorProps } from './src/connector_selector';
12 changes: 12 additions & 0 deletions x-pack/solutions/security/packages/connectors/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

module.exports = {
preset: '@kbn/test',
roots: ['<rootDir>/x-pack/solutions/security/packages/connectors'],
rootDir: '../../../../..',
};
9 changes: 9 additions & 0 deletions x-pack/solutions/security/packages/connectors/kibana.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"type": "shared-browser",
"id": "@kbn/security-solution-connectors",
"owner": [
"@elastic/security-threat-hunting-explore"
],
"group": "security",
"visibility": "private"
}
7 changes: 7 additions & 0 deletions x-pack/solutions/security/packages/connectors/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "@kbn/security-solution-connectors",
"private": true,
"version": "1.0.0",
"license": "Elastic License 2.0",
"sideEffects": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { useEuiTheme } from '@elastic/eui';
import { css } from '@emotion/react';

export const useConnectorSelectorStyles = () => {
const { euiTheme } = useEuiTheme();

return {
placeholder: css`
color: ${euiTheme.colors.primary};
margin-right: ${euiTheme.size.xs};
`,
optionDisplay: css`
margin-right: 8px;
overflow: hidden;
text-overflow: ellipsis;
`,
offset: css`
width: 24px;
`,
inputContainer: css`
.euiSuperSelectControl {
border: none;
box-shadow: none;
background: none;
padding-left: 0;
}

.euiFormControlLayoutIcons {
right: 14px;
top: 2px;
}
`,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import {
EuiButtonEmpty,
EuiFlexGroup,
EuiFlexItem,
EuiSuperSelect,
EuiText,
useEuiTheme,
} from '@elastic/eui';
import React, { useCallback, useMemo } from 'react';
import { some } from 'lodash';
import * as i18n from './translations';
import { useConnectorSelectorStyles } from './connector_selector.styles';
import { ADD_NEW_CONNECTOR } from './constants';

export interface ConnectorDetails {
id: string;
name: string;
description: string;
}

export interface ConnectorSelectorProps {
connectors: ConnectorDetails[];
onChange: (connectorId: string) => void;
selectedId?: string;
onNewConnectorClicked?: () => void;
isDisabled?: boolean;
}

export const ConnectorSelector = React.memo<ConnectorSelectorProps>(
({ connectors, onChange, selectedId, onNewConnectorClicked, isDisabled }) => {
const styles = useConnectorSelectorStyles();
const { euiTheme } = useEuiTheme();

const addNewConnectorOption = useMemo(() => {
return {
value: ADD_NEW_CONNECTOR,
inputDisplay: i18n.ADD_NEW_CONNECTOR,
dropdownDisplay: (
<EuiFlexGroup gutterSize="none" key={ADD_NEW_CONNECTOR}>
<EuiFlexItem grow={true}>
<EuiButtonEmpty
data-test-subj="addNewConnectorButton"
href="#"
isDisabled={isDisabled}
iconType="plus"
size="xs"
>
{i18n.ADD_NEW_CONNECTOR}
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem grow={false}>
{/* Right offset to compensate for 'selected' icon of EuiSuperSelect since native footers aren't supported*/}
<div css={styles.offset} />
</EuiFlexItem>
</EuiFlexGroup>
),
};
}, [isDisabled, styles.offset]);

const connectorExists = useMemo(
() => some(connectors, ['id', selectedId]),
[connectors, selectedId]
);

const mappedConnectorOptions = connectors.map((connector) => ({
value: connector.id,
'data-test-subj': connector.id,
inputDisplay: (
<EuiText css={styles.optionDisplay} size="s" color={euiTheme.colors.primary}>
{connector.name}
</EuiText>
),
dropdownDisplay: (
<React.Fragment key={connector.id}>
<EuiFlexGroup justifyContent="spaceBetween" gutterSize="none" alignItems="center">
<EuiFlexItem grow={false} data-test-subj={`connector-${connector.name}`}>
<strong>{connector.name}</strong>
<EuiText size="xs" color="subdued">
<p>{connector.description}</p>
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
</React.Fragment>
),
}));

const allConnectorOptions = useMemo(
() =>
onNewConnectorClicked
? [...mappedConnectorOptions, addNewConnectorOption]
: [...mappedConnectorOptions],
[onNewConnectorClicked, mappedConnectorOptions, addNewConnectorOption]
);

const onChangeConnector = useCallback(
(connectorId: string) => {
if (connectorId === ADD_NEW_CONNECTOR) {
onNewConnectorClicked?.();
return;
}
onChange(connectorId);
},
[onChange, onNewConnectorClicked]
);

return (
<div css={styles.inputContainer}>
{!connectorExists && !connectors.length ? (
<EuiButtonEmpty
data-test-subj="addNewConnectorButton"
iconType="plusInCircle"
isDisabled={isDisabled}
size="xs"
onClick={() => onNewConnectorClicked?.()}
>
{i18n.ADD_CONNECTOR}
</EuiButtonEmpty>
) : (
<EuiSuperSelect
aria-label={i18n.CONNECTOR_SELECTOR_TITLE}
css={styles.placeholder}
compressed={true}
data-test-subj="connector-selector"
disabled={isDisabled}
hasDividers={true}
onChange={onChangeConnector}
options={allConnectorOptions}
valueOfSelected={selectedId}
placeholder={i18n.CONNECTOR_SELECTOR_PLACEHOLDER}
popoverProps={{ panelMinWidth: 400, anchorPosition: 'downRight' }}
/>
)}
</div>
);
}
);

ConnectorSelector.displayName = 'ConnectorSelector';
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

export const ADD_NEW_CONNECTOR = 'ADD_NEW_CONNECTOR';
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { i18n } from '@kbn/i18n';

export const CONNECTOR_SELECTOR_TITLE = i18n.translate(
'securitySolutionPackages.connectors.connectorSelector.ariaLabel',
{
defaultMessage: 'Connector Selector',
}
);

export const ADD_NEW_CONNECTOR = i18n.translate(
'securitySolutionPackages.connectors.connectorSelector.newConnectorOptions',
{
defaultMessage: 'Add new Connector...',
}
);

export const ADD_CONNECTOR = i18n.translate(
'securitySolutionPackages.connectors.connectorSelector.addConnectorButtonLabel',
{
defaultMessage: 'Add connector',
}
);

export const CONNECTOR_SELECTOR_PLACEHOLDER = i18n.translate(
'securitySolutionPackages.connectors.connectorSelectorInline.connectorPlaceholder',
{
defaultMessage: 'Select a connector',
}
);
19 changes: 19 additions & 0 deletions x-pack/solutions/security/packages/connectors/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"extends": "../../../../../tsconfig.base.json",
"compilerOptions": {
"outDir": "target/types",
"types": [
"jest",
"node",
"react",
"@emotion/react/types/css-prop",
"@testing-library/jest-dom",
"@testing-library/react",
]
},
"include": ["**/*.ts", "**/*.tsx"],
"kbn_references": [
"@kbn/i18n",
],
"exclude": ["target/**/*"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const LocalStorageKey = {
selectedIntegrationTabId: 'securitySolution.onboarding.selectedIntegrationTabId',
selectedCardItemId: 'securitySolution.onboarding.selectedCardItem',
integrationSearchTerm: 'securitySolution.onboarding.integrationSearchTerm',
assistantConnectorId: 'securitySolution.onboarding.assistantCard.connectorId',
} as const;

/**
Expand Down Expand Up @@ -80,3 +81,9 @@ export const useStoredIntegrationSearchTerm = (spaceId: string) =>
`${LocalStorageKey.integrationSearchTerm}.${spaceId}`,
null
);

/**
* Stores the integration search term per space
*/
export const useStoredAssistantConnectorId = (spaceId: string) =>
useDefinedLocalStorage<string | null>(`${LocalStorageKey.assistantConnectorId}.${spaceId}`, null);
Loading
Loading