Skip to content

Commit

Permalink
[Search] Fix index_name not proposed if query matches existing index (#…
Browse files Browse the repository at this point in the history
…178480)

## Summary

If user input partially matches existing index name in the attach index
box, then the user is only presented with options to select existing
index names. Only when the user input doesn't match existing index
names, the user is shown the option to `Create new {} index`. Current
logic still "works" for partially matched index names, as the user can
hit `enter` key to accept current input, but it's not communicated
clearly.

We want be clear that any valid index name can be attached to the
connector. In a case that user input matches existing index name, we
want to somehow communicate that user is not forced to only select
existing indices.

#### Proposed solution

-
[customOptionText](https://github.com/elastic/eui/blob/0396b26fd04796a1d5580cf59ba73fc377fa3c42/src/components/combo_box/combo_box_options_list/combo_box_options_list.tsx#L47-L51)
shows up only when there are no matches with existing index names. The
EUI component doesn't allow us to show it `always` - it's a limitation
- My workaround is to inject to list of options, a custom option related
to user input, if the user input is partial, but not a full match to
existing index names.
- Additionally group options in the `Create new index` and `Select
existing index` categories


### Preview

#### Status quo
<img width="857" alt="Screenshot 2024-03-12 at 13 48 41"
src="https://github.com/elastic/kibana/assets/14121688/91b9813b-11d2-48ca-9f99-8ea34d5ba9ab">

#### Changed flow

Screenshot
<img width="699" alt="Screenshot 2024-03-12 at 13 53 59"
src="https://github.com/elastic/kibana/assets/14121688/3c2eb294-ef18-4be9-b930-e9ee3bf01f78">

Video


https://github.com/elastic/kibana/assets/14121688/b57e9cd6-6922-420f-a020-1ae77564752f



### Checklist

Delete any items that are not applicable to this PR.

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [ ]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [ ] [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
- [ ] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [ ] 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))
- [ ] If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)
- [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))
- [ ] 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
jedrazb and kibanamachine authored Mar 12, 2024
1 parent c1f4821 commit 7981e5e
Showing 1 changed file with 60 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,20 @@ import { FetchAllIndicesAPILogic } from '../../api/index/fetch_all_indices_api_l

import { AttachIndexLogic } from './attach_index_logic';

const CREATE_NEW_INDEX_GROUP_LABEL = i18n.translate(
'xpack.enterpriseSearch.attachIndexBox.optionsGroup.createNewIndex',
{
defaultMessage: 'Create new index',
}
);

const SELECT_EXISTING_INDEX_GROUP_LABEL = i18n.translate(
'xpack.enterpriseSearch.attachIndexBox.optionsGroup.selectExistingIndex',
{
defaultMessage: 'Select existing index',
}
);

export interface AttachIndexBoxProps {
connector: Connector;
}
Expand All @@ -58,7 +72,11 @@ export const AttachIndexBox: React.FC<AttachIndexBoxProps> = ({ connector }) =>
: undefined
);
const [selectedLanguage] = useState<string>();
const [query, setQuery] = useState<string>();
const [query, setQuery] = useState<{
hasMatchingOptions: boolean;
isFullMatch: boolean;
searchValue: string;
}>();

const { makeRequest } = useActions(FetchAllIndicesAPILogic);
const { data, status } = useValues(FetchAllIndicesAPILogic);
Expand All @@ -72,13 +90,33 @@ export const AttachIndexBox: React.FC<AttachIndexBoxProps> = ({ connector }) =>
}
};

const options: Array<EuiComboBoxOptionOption<{ label: string }>> = isLoading
const options: Array<EuiComboBoxOptionOption<string>> = isLoading
? []
: data?.indices.map((index) => {
return {
label: index.name,
};
}) ?? [];

const shouldPrependUserInputAsOption =
!!query?.searchValue && query.hasMatchingOptions && !query.isFullMatch;

const groupedOptions: Array<EuiComboBoxOptionOption<string>> = shouldPrependUserInputAsOption
? [
...[
{
label: CREATE_NEW_INDEX_GROUP_LABEL,
options: [
{
label: query.searchValue,
},
],
},
],
...[{ label: SELECT_EXISTING_INDEX_GROUP_LABEL, options }],
]
: [{ label: SELECT_EXISTING_INDEX_GROUP_LABEL, options }];

useEffect(() => {
setConnector(connector);
makeRequest({});
Expand All @@ -89,7 +127,7 @@ export const AttachIndexBox: React.FC<AttachIndexBoxProps> = ({ connector }) =>

useEffect(() => {
if (query) {
checkIndexExists({ indexName: query });
checkIndexExists({ indexName: query.searchValue });
}
}, [query]);

Expand All @@ -107,7 +145,7 @@ export const AttachIndexBox: React.FC<AttachIndexBoxProps> = ({ connector }) =>
}, [hash]);

const error =
!!query && indexExists[query]
!!query && indexExists[query.searchValue]
? i18n.translate(
'xpack.enterpriseSearch.attachIndexBox.euiFormRow.associatedIndexErrorTextLabel',
{
Expand Down Expand Up @@ -167,15 +205,30 @@ export const AttachIndexBox: React.FC<AttachIndexBoxProps> = ({ connector }) =>
}
)}
isLoading={isLoading}
options={options}
options={groupedOptions}
onSearchChange={(searchValue, hasMatchingOptions) => {
setQuery({
hasMatchingOptions: !!hasMatchingOptions,
isFullMatch: options.some((option) => option.label === searchValue),
searchValue,
});
}}
onChange={(selection) => {
setSelectedIndex(selection[0] || undefined);
const currentSelection = selection[0] ?? undefined;
const selectedIndexOption = currentSelection
? {
label: currentSelection.label,
shouldCreate:
shouldPrependUserInputAsOption &&
!!(currentSelection?.label === query?.searchValue),
}
: undefined;
setSelectedIndex(selectedIndexOption);
}}
selectedOptions={selectedIndex ? [selectedIndex] : undefined}
onCreateOption={(value) => {
setSelectedIndex({ label: value.trim(), shouldCreate: true });
}}
onSearchChange={(value) => setQuery(value)}
singleSelection
/>
</EuiFormRow>
Expand Down

0 comments on commit 7981e5e

Please sign in to comment.