From 13db49aab7d1e43eb7e5b427b7cd8143289e6928 Mon Sep 17 00:00:00 2001 From: "Keith J. Grant" Date: Wed, 16 Mar 2022 13:25:51 -0700 Subject: [PATCH] display current page name in document title --- awx/ui/src/App.js | 13 ++----------- .../components/ScreenHeader/ScreenHeader.js | 13 ++++++++++++- awx/ui/src/hooks/useTitle.js | 19 +++++++++++++++++++ .../screens/ActivityStream/ActivityStream.js | 2 ++ awx/ui/src/setupTests.js | 1 + 5 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 awx/ui/src/hooks/useTitle.js diff --git a/awx/ui/src/App.js b/awx/ui/src/App.js index 674dec8b07..bf1701eec9 100644 --- a/awx/ui/src/App.js +++ b/awx/ui/src/App.js @@ -27,7 +27,7 @@ import { isAuthenticated } from 'util/auth'; import { getLanguageWithoutRegionCode } from 'util/language'; import Metrics from 'screens/Metrics'; import SubscriptionEdit from 'screens/Setting/Subscription/SubscriptionEdit'; -import { RootAPI } from 'api'; +import useTitle from 'hooks/useTitle'; import { dynamicActivate, locales } from './i18nLoader'; import getRouteConfig from './routeConfig'; import { SESSION_REDIRECT_URL } from './constants'; @@ -150,16 +150,7 @@ function App() { dynamicActivate(language); }, [language]); - useEffect(() => { - async function fetchBrandName() { - const { - data: { BRAND_NAME }, - } = await RootAPI.readAssetVariables(); - - document.title = BRAND_NAME; - } - fetchBrandName(); - }, []); + useTitle(); const redirectURL = window.sessionStorage.getItem(SESSION_REDIRECT_URL); if (redirectURL) { diff --git a/awx/ui/src/components/ScreenHeader/ScreenHeader.js b/awx/ui/src/components/ScreenHeader/ScreenHeader.js index 670f8a4f51..eeb2b5f990 100644 --- a/awx/ui/src/components/ScreenHeader/ScreenHeader.js +++ b/awx/ui/src/components/ScreenHeader/ScreenHeader.js @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; +import useTitle from 'hooks/useTitle'; import { t } from '@lingui/macro'; import { @@ -12,7 +13,7 @@ import { Tooltip, } from '@patternfly/react-core'; import { HistoryIcon } from '@patternfly/react-icons'; -import { Link, Route, useRouteMatch } from 'react-router-dom'; +import { Link, Route, useRouteMatch, useLocation } from 'react-router-dom'; const ScreenHeader = ({ breadcrumbConfig, streamType }) => { const { light } = PageSectionVariants; @@ -20,6 +21,16 @@ const ScreenHeader = ({ breadcrumbConfig, streamType }) => { path: Object.keys(breadcrumbConfig)[0], strict: true, }); + + const location = useLocation(); + const parts = location.pathname.split('/'); + if (parts.length > 2) { + parts.pop(); + } + + const pathTitle = breadcrumbConfig[parts.join('/')]; + useTitle(pathTitle); + const isOnlyOneCrumb = oneCrumbMatch && oneCrumbMatch.isExact; return ( diff --git a/awx/ui/src/hooks/useTitle.js b/awx/ui/src/hooks/useTitle.js new file mode 100644 index 0000000000..3f960ccb21 --- /dev/null +++ b/awx/ui/src/hooks/useTitle.js @@ -0,0 +1,19 @@ +import { useEffect } from 'react'; +import useBrandName from './useBrandName'; + +export default function useTitle(title) { + const brandName = useBrandName(); + + useEffect(() => { + const prevTitle = document.title; + if (title) { + document.title = `${brandName} | ${title}`; + } else { + document.title = brandName; + } + + return () => { + document.title = prevTitle; + }; + }, [title, brandName]); +} diff --git a/awx/ui/src/screens/ActivityStream/ActivityStream.js b/awx/ui/src/screens/ActivityStream/ActivityStream.js index c4e196ae42..505608120e 100644 --- a/awx/ui/src/screens/ActivityStream/ActivityStream.js +++ b/awx/ui/src/screens/ActivityStream/ActivityStream.js @@ -20,6 +20,7 @@ import PaginatedTable, { getSearchableKeys, } from 'components/PaginatedTable'; import useRequest from 'hooks/useRequest'; +import useTitle from 'hooks/useTitle'; import { getQSConfig, parseQueryString, updateQueryString } from 'util/qs'; import { ActivityStreamAPI } from 'api'; @@ -31,6 +32,7 @@ function ActivityStream() { const [isTypeDropdownOpen, setIsTypeDropdownOpen] = useState(false); const location = useLocation(); const history = useHistory(); + useTitle(t`Activity Stream`); const urlParams = new URLSearchParams(location.search); const activityStreamType = urlParams.get('type') || 'all'; diff --git a/awx/ui/src/setupTests.js b/awx/ui/src/setupTests.js index b9d84f3803..9625b30276 100644 --- a/awx/ui/src/setupTests.js +++ b/awx/ui/src/setupTests.js @@ -61,6 +61,7 @@ jest.mock('axios', () => ({ }, }), })); +jest.mock('hooks/useTitle'); afterEach(() => { if (networkRequestUrl) {