From 29bdda54426c0855f5e8d67a1dbecf175e5f90f7 Mon Sep 17 00:00:00 2001 From: Nikita Karpukhin Date: Tue, 15 Nov 2022 12:46:46 +0100 Subject: [PATCH] deprecate UserSettingsTab in favour of SettingsLayout.Route Signed-off-by: Nikita Karpukhin --- .changeset/itchy-walls-boil.md | 5 +++ packages/app/src/App.tsx | 6 +-- plugins/user-settings/README.md | 8 ++-- plugins/user-settings/api-report.md | 13 ------ .../DefaultSettingsPage.test.tsx | 6 +-- .../DefaultSettingsPage.tsx | 11 ++--- .../SettingsLayout/SettingsLayout.tsx | 9 ++-- .../SettingsPage/SettingsPage.test.tsx | 5 +-- .../components/SettingsPage/SettingsPage.tsx | 23 +++++++--- .../UserSettingsTab/UserSettingsTab.tsx | 42 ------------------- .../src/components/UserSettingsTab/index.ts | 17 -------- plugins/user-settings/src/components/index.ts | 1 - 12 files changed, 43 insertions(+), 103 deletions(-) create mode 100644 .changeset/itchy-walls-boil.md delete mode 100644 plugins/user-settings/src/components/UserSettingsTab/UserSettingsTab.tsx delete mode 100644 plugins/user-settings/src/components/UserSettingsTab/index.ts diff --git a/.changeset/itchy-walls-boil.md b/.changeset/itchy-walls-boil.md new file mode 100644 index 0000000000..fa498ad948 --- /dev/null +++ b/.changeset/itchy-walls-boil.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-user-settings': minor +--- + +Deprecated UserSettingsTab in favour of SettingsLayout.Route diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index 2526f6740f..fd73e99bcb 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -80,8 +80,8 @@ import { TextSize, } from '@backstage/plugin-techdocs-module-addons-contrib'; import { + SettingsLayout, UserSettingsPage, - UserSettingsTab, } from '@backstage/plugin-user-settings'; import { AdvancedSettings } from './components/advancedSettings'; import AlarmIcon from '@material-ui/icons/Alarm'; @@ -267,9 +267,9 @@ const routes = ( element={} /> }> - + - + } /> } /> diff --git a/plugins/user-settings/README.md b/plugins/user-settings/README.md index 07e1d6dcbb..9a99a69b36 100644 --- a/plugins/user-settings/README.md +++ b/plugins/user-settings/README.md @@ -71,20 +71,20 @@ const AppRoutes = () => ( By default, the plugin renders 3 tabs of settings; GENERAL, AUTHENTICATION PROVIDERS, and FEATURE FLAGS. If you want to add more options for your users, -just pass the extra tabs using `UserSettingsTab` components as children of the `UserSettingsPage` route. +just pass the extra tabs using `SettingsLayout.Route` components as children of the `UserSettingsPage` route. The path is in this case a child of the settings path, in the example below it would be `/settings/advanced` so that you can easily link to it. ```tsx import { + SettingsLayout, UserSettingsPage, - UserSettingsTab, } from '@backstage/plugin-user-settings'; }> - + - + ; ``` diff --git a/plugins/user-settings/api-report.md b/plugins/user-settings/api-report.md index 6167e343d6..f83c97ff73 100644 --- a/plugins/user-settings/api-report.md +++ b/plugins/user-settings/api-report.md @@ -17,7 +17,6 @@ import { JsonValue } from '@backstage/types'; import { Observable } from '@backstage/types'; import { ProfileInfo } from '@backstage/core-plugin-api'; import { ProfileInfoApi } from '@backstage/core-plugin-api'; -import { PropsWithChildren } from 'react'; import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; import { SessionApi } from '@backstage/core-plugin-api'; @@ -70,9 +69,6 @@ export type SettingsLayoutRouteProps = { >; }; -// @public (undocumented) -export const USER_SETTINGS_TAB_KEY = 'user-settings.tab'; - // @public (undocumented) export const UserSettingsAppearanceCard: () => JSX.Element; @@ -144,15 +140,6 @@ export class UserSettingsStorage implements StorageApi { snapshot(key: string): StorageValueSnapshot; } -// @public -export const UserSettingsTab: (props: UserSettingsTabProps) => JSX.Element; - -// @public (undocumented) -export type UserSettingsTabProps = PropsWithChildren<{ - path: string; - title: string; -}>; - // @public (undocumented) export const UserSettingsThemeToggle: () => JSX.Element; diff --git a/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx index d7bedbd5ca..54f10a4c5a 100644 --- a/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx +++ b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx @@ -17,8 +17,8 @@ import React from 'react'; import { renderWithEffects, wrapInTestApp } from '@backstage/test-utils'; import { DefaultSettingsPage } from './DefaultSettingsPage'; -import { UserSettingsTab } from '../UserSettingsTab'; import { useOutlet } from 'react-router'; +import { SettingsLayout } from '../SettingsLayout'; jest.mock('react-router', () => ({ ...jest.requireActual('react-router'), @@ -41,9 +41,9 @@ describe('', () => { it('should render the settings page with 4 tabs when extra tabs are provided', async () => { const advancedTabRoute = ( - +
Advanced settings
-
+ ); const { container } = await renderWithEffects( wrapInTestApp(), diff --git a/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.tsx b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.tsx index 6348845763..6b5b63d6bd 100644 --- a/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.tsx +++ b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.tsx @@ -18,14 +18,13 @@ import React from 'react'; import { UserSettingsAuthProviders } from '../AuthProviders'; import { UserSettingsFeatureFlags } from '../FeatureFlags'; import { UserSettingsGeneral } from '../General'; -import { SettingsLayout } from '../SettingsLayout'; -import { UserSettingsTabProps } from '../UserSettingsTab'; +import { SettingsLayout, SettingsLayoutRouteProps } from '../SettingsLayout'; /** * @public */ export const DefaultSettingsPage = (props: { - tabs?: React.ReactElement[]; + tabs?: React.ReactElement[]; providerSettings?: JSX.Element; }) => { const { providerSettings, tabs } = props; @@ -44,11 +43,7 @@ export const DefaultSettingsPage = (props: { - {tabs?.map((child, i) => ( - - {child} - - ))} + {tabs} ); }; diff --git a/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx b/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx index c120c87122..ac6e34ced9 100644 --- a/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx +++ b/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx @@ -35,10 +35,11 @@ export type SettingsLayoutRouteProps = { tabProps?: TabProps; }; -const dataKey = 'plugin.user-settings.settingsLayoutRoute'; +export const LAYOUT_ROUTE_DATA_KEY = 'plugin.user-settings.settingsLayoutRoute'; +export const LAYOUT_DATA_KEY = 'plugin.user-settings.settingsLayout'; const Route: (props: SettingsLayoutRouteProps) => null = () => null; -attachComponentData(Route, dataKey, true); +attachComponentData(Route, LAYOUT_ROUTE_DATA_KEY, true); // This causes all mount points that are discovered within this route to use the path of the route itself attachComponentData(Route, 'core.gatherMountPoints', true); @@ -60,7 +61,7 @@ export const SettingsLayout = (props: SettingsLayoutProps) => { const routes = useElementFilter(children, elements => elements .selectByComponentData({ - key: dataKey, + key: LAYOUT_ROUTE_DATA_KEY, withStrictError: 'Child of SettingsLayout must be an SettingsLayout.Route', }) @@ -76,4 +77,6 @@ export const SettingsLayout = (props: SettingsLayoutProps) => { ); }; +attachComponentData(SettingsLayout, LAYOUT_DATA_KEY, true); + SettingsLayout.Route = Route; diff --git a/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx b/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx index 883358de5e..c2fc3d63b0 100644 --- a/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx +++ b/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx @@ -17,7 +17,6 @@ import React from 'react'; import { renderWithEffects, wrapInTestApp } from '@backstage/test-utils'; import { SettingsPage } from './SettingsPage'; -import { UserSettingsTab } from '../UserSettingsTab'; import { useOutlet } from 'react-router'; import { SettingsLayout } from '../SettingsLayout'; @@ -42,9 +41,9 @@ describe('', () => { it('should render the default settings page with 4 tabs when extra tabs are provided', async () => { const advancedTabRoute = ( - +
Advanced settings
-
+ ); (useOutlet as jest.Mock).mockReturnValue(advancedTabRoute); const { container } = await renderWithEffects( diff --git a/plugins/user-settings/src/components/SettingsPage/SettingsPage.tsx b/plugins/user-settings/src/components/SettingsPage/SettingsPage.tsx index 8559bcd8c8..eec386d60e 100644 --- a/plugins/user-settings/src/components/SettingsPage/SettingsPage.tsx +++ b/plugins/user-settings/src/components/SettingsPage/SettingsPage.tsx @@ -18,25 +18,36 @@ import React from 'react'; import { DefaultSettingsPage } from '../DefaultSettingsPage'; import { useElementFilter } from '@backstage/core-plugin-api'; import { - USER_SETTINGS_TAB_KEY, - UserSettingsTabProps, -} from '../UserSettingsTab'; + SettingsLayoutProps, + SettingsLayoutRouteProps, +} from '../SettingsLayout'; +import { + LAYOUT_DATA_KEY, + LAYOUT_ROUTE_DATA_KEY, +} from '../SettingsLayout/SettingsLayout'; /** @public */ export const SettingsPage = (props: { providerSettings?: JSX.Element }) => { const { providerSettings } = props; const outlet = useOutlet(); + const layout = useElementFilter(outlet, elements => + elements + .selectByComponentData({ + key: LAYOUT_DATA_KEY, + }) + .getElements(), + ); const tabs = useElementFilter(outlet, elements => elements .selectByComponentData({ - key: USER_SETTINGS_TAB_KEY, + key: LAYOUT_ROUTE_DATA_KEY, }) - .getElements(), + .getElements(), ); return ( <> - {(tabs.length === 0 && outlet) || ( + {(layout.length !== 0 && layout) || ( )} diff --git a/plugins/user-settings/src/components/UserSettingsTab/UserSettingsTab.tsx b/plugins/user-settings/src/components/UserSettingsTab/UserSettingsTab.tsx deleted file mode 100644 index 171c54ecf3..0000000000 --- a/plugins/user-settings/src/components/UserSettingsTab/UserSettingsTab.tsx +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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, { PropsWithChildren } from 'react'; -import { attachComponentData } from '@backstage/core-plugin-api'; - -/** @public */ -export const USER_SETTINGS_TAB_KEY = 'user-settings.tab'; - -/** @public */ -export type UserSettingsTabProps = PropsWithChildren<{ - /** - * The path to the tab in the settings route - * @example `/settings/advanced` - */ - path: string; - /** The title of the tab. It will also reflect in the document title when the tab is active */ - title: string; -}>; - -/** - * Renders a tab inside the settings page - * @param props - Component props - * @public - */ -export const UserSettingsTab = (props: UserSettingsTabProps) => { - return <>{props.children}; -}; - -attachComponentData(UserSettingsTab, USER_SETTINGS_TAB_KEY, 'UserSettingsTab'); diff --git a/plugins/user-settings/src/components/UserSettingsTab/index.ts b/plugins/user-settings/src/components/UserSettingsTab/index.ts deleted file mode 100644 index d0645d4efb..0000000000 --- a/plugins/user-settings/src/components/UserSettingsTab/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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'; diff --git a/plugins/user-settings/src/components/index.ts b/plugins/user-settings/src/components/index.ts index 8eb43a7a10..deb2761628 100644 --- a/plugins/user-settings/src/components/index.ts +++ b/plugins/user-settings/src/components/index.ts @@ -20,5 +20,4 @@ export * from './AuthProviders'; export * from './General'; export * from './FeatureFlags'; export { useUserProfile } from './useUserProfileInfo'; -export * from './UserSettingsTab'; export * from './SettingsLayout';