From ae53c3a11cdfe8a6909b7b5792ec4b200c059ce7 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 1 Jul 2022 11:12:34 +0200 Subject: [PATCH] refactor: extract use search result location hook Signed-off-by: Camila Belo --- .../CatalogSearchResultListItem.tsx | 14 ++++---- .../DefaultResultListItem.tsx | 15 ++------ .../components/DefaultResultListItem/index.ts | 1 + .../useSearchResultLocation.tsx | 36 +++++++++++++++++++ .../TechDocsSearchResultListItem.tsx | 25 +++++-------- 5 files changed, 55 insertions(+), 36 deletions(-) create mode 100644 plugins/search-react/src/components/DefaultResultListItem/useSearchResultLocation.tsx diff --git a/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx b/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx index 807ba611d9..cc9dc0f441 100644 --- a/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx +++ b/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx @@ -25,12 +25,15 @@ import { makeStyles, } from '@material-ui/core'; import { Link } from '@backstage/core-components'; -import { configApiRef, useAnalytics, useApi } from '@backstage/core-plugin-api'; +import { useAnalytics } from '@backstage/core-plugin-api'; import { IndexableDocument, ResultHighlight, } from '@backstage/plugin-search-common'; -import { HighlightedSearchResultText } from '@backstage/plugin-search-react'; +import { + HighlightedSearchResultText, + useSearchResultLocation, +} from '@backstage/plugin-search-react'; const useStyles = makeStyles({ flexContainer: { @@ -64,12 +67,7 @@ export function CatalogSearchResultListItem( const classes = useStyles(); const analytics = useAnalytics(); - const configApi = useApi(configApiRef); - let to = result.location; - // Is relative url - if (!to.match(/^([a-z]*:)?\/\//i)) { - to = configApi.getString('app.baseUrl').concat(to); - } + const to = useSearchResultLocation(result); const handleClick = () => { analytics.captureEvent('discover', result.title, { diff --git a/plugins/search-react/src/components/DefaultResultListItem/DefaultResultListItem.tsx b/plugins/search-react/src/components/DefaultResultListItem/DefaultResultListItem.tsx index fabf61c813..2e81f50d2e 100644 --- a/plugins/search-react/src/components/DefaultResultListItem/DefaultResultListItem.tsx +++ b/plugins/search-react/src/components/DefaultResultListItem/DefaultResultListItem.tsx @@ -15,12 +15,7 @@ */ import React, { ReactNode } from 'react'; -import { - AnalyticsContext, - configApiRef, - useAnalytics, - useApi, -} from '@backstage/core-plugin-api'; +import { AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api'; import { ResultHighlight, SearchDocument, @@ -34,6 +29,7 @@ import { Divider, } from '@material-ui/core'; import { Link } from '@backstage/core-components'; +import { useSearchResultLocation } from './useSearchResultLocation'; /** * Props for {@link DefaultResultListItem} @@ -63,13 +59,8 @@ export const DefaultResultListItemComponent = ({ lineClamp = 5, }: DefaultResultListItemProps) => { const analytics = useAnalytics(); - const configApi = useApi(configApiRef); - let to = result.location; - // Is relative url - if (!to.match(/^([a-z]*:)?\/\//i)) { - to = configApi.getString('app.baseUrl').concat(to); - } + const to = useSearchResultLocation(result); const handleClick = () => { analytics.captureEvent('discover', result.title, { diff --git a/plugins/search-react/src/components/DefaultResultListItem/index.ts b/plugins/search-react/src/components/DefaultResultListItem/index.ts index a555f25c02..0e50f25cec 100644 --- a/plugins/search-react/src/components/DefaultResultListItem/index.ts +++ b/plugins/search-react/src/components/DefaultResultListItem/index.ts @@ -16,3 +16,4 @@ export { DefaultResultListItem } from './DefaultResultListItem'; export type { DefaultResultListItemProps } from './DefaultResultListItem'; +export { useSearchResultLocation } from './useSearchResultLocation'; diff --git a/plugins/search-react/src/components/DefaultResultListItem/useSearchResultLocation.tsx b/plugins/search-react/src/components/DefaultResultListItem/useSearchResultLocation.tsx new file mode 100644 index 0000000000..c80d335354 --- /dev/null +++ b/plugins/search-react/src/components/DefaultResultListItem/useSearchResultLocation.tsx @@ -0,0 +1,36 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { configApiRef, useApi } from '@backstage/core-plugin-api'; +import { SearchDocument } from '@backstage/plugin-search-common'; + +/** + * Builds a search result url. + * @param document - A search result item. + * @returns Add app base url as location prefix when location is relative. + */ +export const useSearchResultLocation = (document: SearchDocument) => { + const configApi = useApi(configApiRef); + + let location = document.location; + + const isRelative = !location.match(/^([a-z]*:)?\/\//i); + if (isRelative) { + location = configApi.getString('app.baseUrl').concat(location); + } + + return location; +}; diff --git a/plugins/techdocs/src/search/components/TechDocsSearchResultListItem.tsx b/plugins/techdocs/src/search/components/TechDocsSearchResultListItem.tsx index d0969ee075..bd92bde88c 100644 --- a/plugins/techdocs/src/search/components/TechDocsSearchResultListItem.tsx +++ b/plugins/techdocs/src/search/components/TechDocsSearchResultListItem.tsx @@ -23,9 +23,12 @@ import { makeStyles, } from '@material-ui/core'; import { Link } from '@backstage/core-components'; -import { configApiRef, useAnalytics, useApi } from '@backstage/core-plugin-api'; +import { useAnalytics } from '@backstage/core-plugin-api'; import { ResultHighlight } from '@backstage/plugin-search-common'; -import { HighlightedSearchResultText } from '@backstage/plugin-search-react'; +import { + HighlightedSearchResultText, + useSearchResultLocation, +} from '@backstage/plugin-search-react'; const useStyles = makeStyles({ flexContainer: { @@ -74,14 +77,10 @@ export const TechDocsSearchResultListItem = ( const classes = useStyles(); const analytics = useAnalytics(); - const configApi = useApi(configApiRef); + + const to = useSearchResultLocation(result); const handleClick = () => { - let to = result.location; - // Is relative url - if (!to.match(/^([a-z]*:)?\/\//i)) { - to = configApi.getString('app.baseUrl').concat(to); - } analytics.captureEvent('discover', result.title, { attributes: { to }, value: rank, @@ -156,20 +155,14 @@ export const TechDocsSearchResultListItem = ( ); }; - const LinkWrapper = ({ children }: PropsWithChildren<{}>) => { - let to = result.location; - // Is relative url - if (!to.match(/^([a-z]*:)?\/\//i)) { - to = configApi.getString('app.baseUrl').concat(to); - } - return asLink ? ( + const LinkWrapper = ({ children }: PropsWithChildren<{}>) => + asLink ? ( {children} ) : ( <>{children} ); - }; const ListItemWrapper = ({ children }: PropsWithChildren<{}>) => asListItem ? (