Use custom UserSettingsTab component to render extra tabs in settings

Signed-off-by: Yousif Al-Raheem <yousifalraheem@gmail.com>
This commit is contained in:
Yousif Al-Raheem
2022-03-23 14:25:17 +01:00
parent 9049838820
commit 100a7e14dd
6 changed files with 62 additions and 14 deletions
+7 -4
View File
@@ -69,7 +69,10 @@ import {
techdocsPlugin,
TechDocsReaderPage,
} from '@backstage/plugin-techdocs';
import { UserSettingsPage } from '@backstage/plugin-user-settings';
import {
UserSettingsPage,
UserSettingsTab,
} from '@backstage/plugin-user-settings';
import { AdvancedSettings } from './components/advancedSettings';
import AlarmIcon from '@material-ui/icons/Alarm';
import React from 'react';
@@ -216,9 +219,9 @@ const routes = (
element={<CostInsightsLabelDataflowInstructionsPage />}
/>
<Route path="/settings" element={<UserSettingsPage />}>
<Route path="/advanced" element={<AdvancedSettings />}>
Advanced
</Route>
<UserSettingsTab path="/advanced" title="Advanced">
<AdvancedSettings />
</UserSettingsTab>
</Route>
<Route path="/azure-pull-requests" element={<AzurePullRequestsPage />} />
<Route path="/apache-airflow" element={<ApacheAirflowPage />} />
@@ -17,13 +17,14 @@
import React from 'react';
import { renderWithEffects, wrapInTestApp } from '@backstage/test-utils';
import { SettingsPage } from './SettingsPage';
import { UserSettingsTab } from './UserSettingsTab';
jest.mock('react-router', () => ({
...jest.requireActual('react-router'),
useOutlet: jest.fn().mockReturnValue(undefined),
}));
import { useOutlet, Route } from 'react-router';
import { useOutlet } from 'react-router';
describe('<SettingsPage />', () => {
it('should render the settings page with 3 tabs', async () => {
@@ -38,9 +39,9 @@ describe('<SettingsPage />', () => {
it('should render the settings page with 4 tabs when extra tabs are provided', async () => {
const advancedTabRoute = (
<>
<Route path="/advanced" element={<div>Advanced settings</div>}>
Advanced
</Route>
<UserSettingsTab path="/advanced" title="Advanced">
<div>Advanced settings</div>
</UserSettingsTab>
</>
);
(useOutlet as jest.Mock).mockReturnValueOnce(advancedTabRoute);
@@ -56,9 +57,9 @@ describe('<SettingsPage />', () => {
it('should throw error if non compliant route is passed to settings routes', async () => {
const advancedTabRoute = (
<>
<Route path="/advanced" element={<div>Advanced settings</div>}>
Advanced
</Route>
<UserSettingsTab path="/advanced" title="Advanced">
<div>Advanced settings</div>
</UserSettingsTab>
<div>Non compliant element</div>
</>
);
@@ -37,11 +37,11 @@ export const SettingsPage = ({ providerSettings }: Props) => {
const extraTabs = (React.Children.toArray(outlet?.props?.children) ||
[]) as Array<ReactElement>;
const notCompliantTab = Array.from(extraTabs).some(
child => (child.type as any)?.displayName !== 'Route',
child => (child.type as any)?.displayName !== 'UserSettingsTab',
);
if (notCompliantTab) {
throw new Error(
'Invalid element passed to SettingsPage Outlet. You may only pass children of type Route.',
'Invalid element passed to SettingsPage Outlet. You may only pass children of type UserSettingsTab.',
);
}
@@ -64,7 +64,7 @@ export const SettingsPage = ({ providerSettings }: Props) => {
{extraTabs.map((child, i) => {
const path: string = child.props.path;
const title: string = child.props.children;
const title: string = child.props.title;
return (
<TabbedLayout.Route key={i} path={path} title={title}>
@@ -0,0 +1,27 @@
/*
* Copyright 2020 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 React from 'react';
interface Props {
path: string;
title: React.ReactNode;
}
export const UserSettingsTab: React.FC<Props> = ({ children }) => {
return <>{children}</>;
};
UserSettingsTab.displayName = 'UserSettingsTab';
@@ -0,0 +1,16 @@
/*
* Copyright 2020 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.
*/
export * from './UserSettingsTab';
@@ -19,3 +19,4 @@ export * from './AuthProviders';
export * from './General';
export * from './FeatureFlags';
export { useUserProfile } from './useUserProfileInfo';
export * from './UserSettingsTab';