-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[Onboarding] Introduce search index details page locator and update all reference #205005
base: main
Are you sure you want to change the base?
Changes from all commits
761d919
031ad33
acdd102
11de762
d5c621e
fd10893
adba282
a813e6d
7237fb1
adf7a89
a504b82
4bd6ca6
0eafbd9
468f3e6
4023011
ca8dc1d
5df9816
601f509
8116d7d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ | |
* 2.0. | ||
*/ | ||
|
||
import React from 'react'; | ||
import React, { useCallback, useMemo } from 'react'; | ||
|
||
import { useValues, useActions } from 'kea'; | ||
|
||
|
@@ -16,6 +16,7 @@ import { | |
EuiFlyoutBody, | ||
EuiFlyoutHeader, | ||
EuiIcon, | ||
EuiLink, | ||
EuiSpacer, | ||
EuiText, | ||
EuiTitle, | ||
|
@@ -25,14 +26,11 @@ import { i18n } from '@kbn/i18n'; | |
|
||
import { FormattedMessage } from '@kbn/i18n-react'; | ||
|
||
import { ENTERPRISE_SEARCH_CONTENT_PLUGIN } from '../../../../../common/constants'; | ||
|
||
import { EnterpriseSearchApplicationIndex } from '../../../../../common/types/search_applications'; | ||
|
||
import { SEARCH_INDEX_PATH } from '../../../enterprise_search_content/routes'; | ||
import { healthColorsMap } from '../../../shared/constants/health_colors'; | ||
import { generateEncodedPath } from '../../../shared/encode_path_params'; | ||
import { EuiLinkTo } from '../../../shared/react_router_helpers'; | ||
|
||
import { KibanaLogic } from '../../../shared/kibana'; | ||
|
||
import { SearchApplicationIndicesFlyoutLogic } from './search_application_indices_flyout_logic'; | ||
|
||
|
@@ -44,7 +42,36 @@ export const SearchApplicationIndicesFlyout: React.FC = () => { | |
isFlyoutVisible, | ||
} = useValues(SearchApplicationIndicesFlyoutLogic); | ||
const { closeFlyout } = useActions(SearchApplicationIndicesFlyoutLogic); | ||
|
||
const { navigateToUrl, share } = useValues(KibanaLogic); | ||
const searchIndicesLocator = useMemo( | ||
() => share?.url.locators.get('SEARCH_INDEX_DETAILS_LOCATOR_ID'), | ||
[share] | ||
); | ||
const SearchIndicesLinkProps = useCallback( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see other comment. |
||
(indexName: string) => { | ||
const viewIndicesLinkDefaultProps = { | ||
'data-test-subj': 'search-application-index-link', | ||
'data-telemetry-id': 'entSearchApplications-list-viewIndex', | ||
}; | ||
if (searchIndicesLocator) { | ||
return { | ||
...viewIndicesLinkDefaultProps, | ||
href: searchIndicesLocator.getRedirectUrl({}), | ||
onClick: async (event: React.MouseEvent<HTMLAnchorElement>) => { | ||
event.preventDefault(); | ||
const url = await searchIndicesLocator.getUrl({ indexName }); | ||
navigateToUrl(url, { | ||
shouldNotCreateHref: true, | ||
shouldNotPrepend: true, | ||
}); | ||
}, | ||
}; | ||
} else { | ||
return { ...viewIndicesLinkDefaultProps, disabled: true }; | ||
} | ||
}, | ||
[navigateToUrl, searchIndicesLocator] | ||
); | ||
if (!searchApplicationData) return null; | ||
const { indices } = searchApplicationData; | ||
|
||
|
@@ -58,16 +85,7 @@ export const SearchApplicationIndicesFlyout: React.FC = () => { | |
} | ||
), | ||
render: (indexName: string) => ( | ||
<EuiLinkTo | ||
data-test-subj="search-application-index-link" | ||
data-telemetry-id="entSearchApplications-list-viewIndex" | ||
to={`${ENTERPRISE_SEARCH_CONTENT_PLUGIN.URL}${generateEncodedPath(SEARCH_INDEX_PATH, { | ||
indexName, | ||
})}`} | ||
shouldNotCreateHref | ||
> | ||
{indexName} | ||
</EuiLinkTo> | ||
<EuiLink {...SearchIndicesLinkProps(indexName)}>{indexName}</EuiLink> | ||
), | ||
sortable: true, | ||
truncateText: true, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,9 @@ | |
* 2.0. | ||
*/ | ||
|
||
import React, { useState } from 'react'; | ||
import React, { useMemo, useState } from 'react'; | ||
|
||
import { useValues } from 'kea'; | ||
|
||
import { | ||
EuiButtonIcon, | ||
|
@@ -28,10 +30,11 @@ import { Connector } from '@kbn/search-connectors'; | |
|
||
import { MANAGE_API_KEYS_URL } from '../../../../../../common/constants'; | ||
import { generateEncodedPath } from '../../../../shared/encode_path_params'; | ||
import { KibanaLogic } from '../../../../shared/kibana'; | ||
import { EuiLinkTo } from '../../../../shared/react_router_helpers'; | ||
|
||
import { ApiKey } from '../../../api/connector/generate_connector_api_key_api_logic'; | ||
import { CONNECTOR_DETAIL_PATH, SEARCH_INDEX_PATH } from '../../../routes'; | ||
import { CONNECTOR_DETAIL_PATH } from '../../../routes'; | ||
|
||
export interface GeneratedConfigFieldsProps { | ||
apiKey?: ApiKey; | ||
|
@@ -84,7 +87,7 @@ export const GeneratedConfigFields: React.FC<GeneratedConfigFieldsProps> = ({ | |
isGenerateLoading, | ||
}) => { | ||
const [isModalVisible, setIsModalVisible] = useState(false); | ||
|
||
const { navigateToUrl, share } = useValues(KibanaLogic); | ||
const refreshButtonClick = () => { | ||
setIsModalVisible(true); | ||
}; | ||
|
@@ -96,6 +99,33 @@ export const GeneratedConfigFields: React.FC<GeneratedConfigFieldsProps> = ({ | |
if (generateApiKey) generateApiKey(); | ||
setIsModalVisible(false); | ||
}; | ||
const searchIndexDetailsUrl = share?.url.locators | ||
.get('SEARCH_INDEX_DETAILS_LOCATOR_ID') | ||
?.useUrl({ indexName: connector?.index_name }); | ||
Comment on lines
+102
to
+104
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this usage of the locator so different from the others? if we can make a sync call that returns the value or |
||
|
||
const SearchIndicesLinkProps = useMemo(() => { | ||
const props = { | ||
target: '_blank', | ||
}; | ||
if (searchIndexDetailsUrl) { | ||
return { | ||
...props, | ||
href: searchIndexDetailsUrl, | ||
onClick: async (event: React.MouseEvent<HTMLAnchorElement>) => { | ||
event.stopImmediatePropagation(); | ||
navigateToUrl(searchIndexDetailsUrl, { | ||
shouldNotCreateHref: true, | ||
shouldNotPrepend: true, | ||
}); | ||
}, | ||
}; | ||
} else { | ||
return { | ||
...props, | ||
disabled: true, | ||
}; | ||
} | ||
}, [navigateToUrl, searchIndexDetailsUrl]); | ||
|
||
const showApiKeyInfoForSelfManagedConnector = !connector.is_native; | ||
const showApiKeyBanner = showApiKeyInfoForSelfManagedConnector && apiKey?.encoded; | ||
|
@@ -184,15 +214,7 @@ export const GeneratedConfigFields: React.FC<GeneratedConfigFieldsProps> = ({ | |
</EuiFlexItem> | ||
<EuiFlexItem> | ||
{connector.index_name && ( | ||
<EuiLinkTo | ||
external | ||
target="_blank" | ||
to={generateEncodedPath(SEARCH_INDEX_PATH, { | ||
indexName: connector.index_name, | ||
})} | ||
> | ||
{connector.index_name} | ||
</EuiLinkTo> | ||
<EuiLink {...SearchIndicesLinkProps}>{connector.index_name}</EuiLink> | ||
)} | ||
</EuiFlexItem> | ||
<EuiFlexItem /> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❌ This is not a good way to use
useCallback()
. That should be used if you want to create a onClick handler for theEuiLink
. This is being used to generate props at render time, which feels like a code smell to me.What you likely want is something more like this:
but the promise in the
useCallback
is problematic, but likely the best option if we do this here. A plus would be this function could be shared between the link and and the action instead of having two handlers.BUT a better option might be to create a link component that takes the index name as a prop and handles all this logic with the locator and share plugin start in that component which is rendered in the column
render()
it could then be used in this file and the flyout