Skip to content

Commit

Permalink
[Search] Sanitize Create and Attach button index name (#179637)
Browse files Browse the repository at this point in the history
## Summary

Index name and connector name have different constrains, to make the
button work, we sanitize the connector name. This was found as a bug
during 8.13 QA.

<img width="579" alt="Screenshot 2024-03-28 at 17 18 35"
src="https://github.com/elastic/kibana/assets/1410658/5ef3719f-73e2-4f5f-b168-8f5e71c3c643">
<img width="632" alt="Screenshot 2024-03-28 at 17 18 37"
src="https://github.com/elastic/kibana/assets/1410658/8f037455-717b-480c-a90d-e524d35a4f76">
<img width="569" alt="Screenshot 2024-03-28 at 17 18 53"
src="https://github.com/elastic/kibana/assets/1410658/fd5240f2-5def-4339-8de0-2eebc2c815da">





### Checklist

Delete any items that are not applicable to this PR.

- [ ] [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
- [ ] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [x] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [x] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [x] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
efegurkan and kibanamachine authored Apr 2, 2024
1 parent fa8363a commit d335594
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import { Status } from '../../../../../common/types/api';

import { FetchAvailableIndicesAPILogic } from '../../api/index/fetch_available_indices_api_logic';

import { formatApiName } from '../../utils/format_api_name';

import { AttachIndexLogic } from './attach_index_logic';

const CREATE_NEW_INDEX_GROUP_LABEL = i18n.translate(
Expand Down Expand Up @@ -77,6 +79,7 @@ export const AttachIndexBox: React.FC<AttachIndexBoxProps> = ({ connector }) =>
isFullMatch: boolean;
searchValue: string;
}>();
const [sanitizedName, setSanitizedName] = useState<string>(formatApiName(connector.name));

const { makeRequest } = useActions(FetchAvailableIndicesAPILogic);
const { data, status } = useValues(FetchAvailableIndicesAPILogic);
Expand Down Expand Up @@ -128,8 +131,8 @@ export const AttachIndexBox: React.FC<AttachIndexBoxProps> = ({ connector }) =>
useEffect(() => {
setConnector(connector);
makeRequest({});
if (!connector.index_name && connector.name) {
checkIndexExists({ indexName: connector.name });
if (!connector.index_name && connector.name && sanitizedName) {
checkIndexExists({ indexName: sanitizedName });
}
}, [connector.id]);

Expand All @@ -140,6 +143,10 @@ export const AttachIndexBox: React.FC<AttachIndexBoxProps> = ({ connector }) =>
}
}, [query]);

useEffect(() => {
setSanitizedName(formatApiName(connector.name));
}, [connector.name]);

const { hash } = useLocation();
useEffect(() => {
if (hash) {
Expand Down Expand Up @@ -283,25 +290,25 @@ export const AttachIndexBox: React.FC<AttachIndexBoxProps> = ({ connector }) =>
color="primary"
fill
onClick={() => {
createIndex({ indexName: connector.name, language: null });
setSelectedIndex({ label: connector.name });
createIndex({ indexName: sanitizedName, language: null });
setSelectedIndex({ label: sanitizedName });
}}
isLoading={isSaveLoading || isExistLoading}
disabled={indexExists[connector.name]}
disabled={indexExists[sanitizedName]}
>
{i18n.translate(
'xpack.enterpriseSearch.attachIndexBox.createSameIndexButtonLabel',
{
defaultMessage: 'Create and attach an index named {indexName}',
values: { indexName: connector.name },
values: { indexName: sanitizedName },
}
)}
</EuiButton>
{indexExists[connector.name] ? (
{indexExists[sanitizedName] ? (
<EuiText size="xs">
{i18n.translate('xpack.enterpriseSearch.attachIndexBox.indexNameExistsError', {
defaultMessage: 'Index with name {indexName} already exists',
values: { indexName: connector.name },
values: { indexName: sanitizedName },
})}
</EuiText>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import {

type NameAndDescription = Partial<Pick<Connector, 'name' | 'description'>>;

type ConnectorNameAndDescriptionActions = Pick<
export type ConnectorNameAndDescriptionActions = Pick<
Actions<PutConnectorNameAndDescriptionArgs, PutConnectorNameAndDescriptionResponse>,
'makeRequest'
'makeRequest' | 'apiSuccess' | 'apiError'
> & {
saveNameAndDescription(nameAndDescription: NameAndDescription): NameAndDescription;
setConnector(connector: Connector): Connector;
Expand All @@ -44,7 +44,7 @@ export const ConnectorNameAndDescriptionLogic = kea<
setConnector: (connector) => connector,
},
connect: {
actions: [ConnectorNameAndDescriptionApiLogic, ['makeRequest']],
actions: [ConnectorNameAndDescriptionApiLogic, ['makeRequest', 'apiSuccess', 'apiError']],
values: [ConnectorNameAndDescriptionApiLogic, ['status']],
},
listeners: ({ actions, values }) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,24 @@ import {
import { FetchIndexActions, FetchIndexApiLogic } from '../../api/index/fetch_index_api_logic';
import { ElasticsearchViewIndex } from '../../types';

import {
ConnectorNameAndDescriptionLogic,
ConnectorNameAndDescriptionActions,
} from './connector_name_and_description_logic';

export interface ConnectorViewActions {
fetchConnector: CachedFetchConnectorByIdApiLogicActions['makeRequest'];
fetchConnectorApiError: CachedFetchConnectorByIdApiLogicActions['apiError'];
fetchConnectorApiReset: CachedFetchConnectorByIdApiLogicActions['apiReset'];
fetchConnectorApiSuccess: CachedFetchConnectorByIdApiLogicActions['apiSuccess'];
startConnectorPoll: CachedFetchConnectorByIdApiLogicActions['startPolling'];
stopConnectorPoll: CachedFetchConnectorByIdApiLogicActions['stopPolling'];
fetchIndex: FetchIndexActions['makeRequest'];
fetchIndexApiError: FetchIndexActions['apiError'];
fetchIndexApiReset: FetchIndexActions['apiReset'];
fetchIndexApiSuccess: FetchIndexActions['apiSuccess'];
nameAndDescriptionApiError: ConnectorNameAndDescriptionActions['apiError'];
nameAndDescriptionApiSuccess: ConnectorNameAndDescriptionActions['apiSuccess'];
startConnectorPoll: CachedFetchConnectorByIdApiLogicActions['startPolling'];
stopConnectorPoll: CachedFetchConnectorByIdApiLogicActions['stopPolling'];
updateConnectorConfiguration: PostConnectorConfigurationActions['makeRequest'];
updateConnectorConfigurationSuccess: PostConnectorConfigurationActions['apiSuccess'];
}
Expand Down Expand Up @@ -101,6 +108,8 @@ export const ConnectorViewLogic = kea<MakeLogicType<ConnectorViewValues, Connect
'makeRequest as updateConnectorConfiguration',
'apiSuccess as updateConnectorConfigurationSuccess',
],
ConnectorNameAndDescriptionLogic,
['apiSuccess as nameAndDescriptionApiSuccess', 'apiError as nameAndDescriptionApiError'],
],
values: [
CachedFetchConnectorByIdApiLogic,
Expand All @@ -118,6 +127,16 @@ export const ConnectorViewLogic = kea<MakeLogicType<ConnectorViewValues, Connect
},
}),
listeners: ({ actions, values }) => ({
nameAndDescriptionApiError: () => {
if (values.connectorId) {
actions.fetchConnector({ connectorId: values.connectorId });
}
},
nameAndDescriptionApiSuccess: () => {
if (values.connectorId) {
actions.fetchConnector({ connectorId: values.connectorId });
}
},
updateConnectorConfigurationSuccess: () => {
if (values.connectorId) {
actions.fetchConnector({ connectorId: values.connectorId });
Expand Down

0 comments on commit d335594

Please sign in to comment.