use attachComponentData instead of displayName in UserSettingsTab

Signed-off-by: Yousif Al-Raheem <yousifalraheem@gmail.com>
This commit is contained in:
yousifalraheem
2022-04-04 14:40:03 +02:00
committed by Yousif Al-Raheem
parent 0d32a893f9
commit 0a0a4fa178
4 changed files with 53 additions and 32 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
---
'@backstage/plugin-user-settings': minor
'@backstage/plugin-user-settings': patch
---
Added the ability to render extra setting tabs
+18 -4
View File
@@ -9,7 +9,7 @@ import { ApiRef } from '@backstage/core-plugin-api';
import { BackstagePlugin } from '@backstage/core-plugin-api';
import { IconComponent } from '@backstage/core-plugin-api';
import { ProfileInfo } from '@backstage/core-plugin-api';
import { default as React_2 } from 'react';
import { PropsWithChildren } from 'react';
import { RouteRef } from '@backstage/core-plugin-api';
import { SessionApi } from '@backstage/core-plugin-api';
@@ -44,6 +44,11 @@ export const Router: ({ providerSettings }: Props) => JSX.Element;
// @public (undocumented)
export const Settings: (props: SettingsProps) => JSX.Element;
// Warning: (ae-missing-release-tag) "USER_SETTINGS_TAB_KEY" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const USER_SETTINGS_TAB_KEY = 'user-settings.tab';
// Warning: (ae-missing-release-tag) "UserSettingsAppearanceCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
@@ -109,11 +114,16 @@ export const UserSettingsProfileCard: () => JSX.Element;
// @public (undocumented)
export const UserSettingsSignInAvatar: ({ size }: Props_5) => JSX.Element;
// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "UserSettingsTab" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
// @public
export const UserSettingsTab: (props: UserSettingsTabProps) => JSX.Element;
// Warning: (ae-missing-release-tag) "UserSettingsTabProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const UserSettingsTab: React_2.FC<Props_6>;
export type UserSettingsTabProps = PropsWithChildren<{
path: string;
title: string;
}>;
// Warning: (ae-missing-release-tag) "UserSettingsThemeToggle" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
@@ -128,4 +138,8 @@ export const useUserProfile: () => {
displayName: string;
loading: boolean;
};
// Warnings were encountered during analysis:
//
// src/components/UserSettingsTab/UserSettingsTab.d.ts:6:17 - (tsdoc-code-span-missing-delimiter) The code span is missing its closing backtick
```
@@ -20,11 +20,13 @@ import {
SidebarPinStateContext,
TabbedLayout,
} from '@backstage/core-components';
import React, { useContext, ReactElement } from 'react';
import React, { useContext } from 'react';
import { useOutlet } from 'react-router';
import { useElementFilter } from '@backstage/core-plugin-api';
import { UserSettingsAuthProviders } from './AuthProviders';
import { UserSettingsFeatureFlags } from './FeatureFlags';
import { UserSettingsGeneral } from './General';
import { USER_SETTINGS_TAB_KEY, UserSettingsTabProps } from './UserSettingsTab';
type Props = {
providerSettings?: JSX.Element;
@@ -34,16 +36,13 @@ export const SettingsPage = ({ providerSettings }: Props) => {
const { isMobile } = useContext(SidebarPinStateContext);
const outlet = useOutlet();
const extraTabs = (React.Children.toArray(outlet?.props?.children) ||
[]) as Array<ReactElement>;
const notCompliantTab = Array.from(extraTabs).some(
child => (child.type as any)?.displayName !== 'UserSettingsTab',
const tabs = useElementFilter(outlet, elements =>
elements
.selectByComponentData({
key: USER_SETTINGS_TAB_KEY,
})
.getElements<UserSettingsTabProps>(),
);
if (notCompliantTab) {
throw new Error(
'Invalid element passed to SettingsPage Outlet. You may only pass children of type UserSettingsTab.',
);
}
return (
<Page themeId="home">
@@ -62,16 +61,11 @@ export const SettingsPage = ({ providerSettings }: Props) => {
<UserSettingsFeatureFlags />
</TabbedLayout.Route>
{extraTabs.map((child, i) => {
const path: string = child.props.path;
const title: string = child.props.title;
return (
<TabbedLayout.Route key={i} path={path} title={title}>
{child}
</TabbedLayout.Route>
);
})}
{tabs.map((child, i) => (
<TabbedLayout.Route key={i} {...child.props}>
{child}
</TabbedLayout.Route>
))}
</TabbedLayout>
</Page>
);
@@ -13,15 +13,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import React, { PropsWithChildren } from 'react';
import { attachComponentData } from '@backstage/core-plugin-api';
interface Props {
export const USER_SETTINGS_TAB_KEY = 'user-settings.tab';
export type UserSettingsTabProps = PropsWithChildren<{
/**
* The path to the tab in the settings route
* @example `/settings/advanced
*/
path: string;
title: React.ReactNode;
}
/** The title of the tab. It will also reflect in the document title when the tab is active */
title: string;
}>;
export const UserSettingsTab: React.FC<Props> = ({ children }) => {
return <>{children}</>;
/**
* Renders a tab inside the settings page
* @param props - Component props
* @public
*/
export const UserSettingsTab = (props: UserSettingsTabProps) => {
return <>{props.children}</>;
};
UserSettingsTab.displayName = 'UserSettingsTab';
attachComponentData(UserSettingsTab, USER_SETTINGS_TAB_KEY, 'UserSettingsTab');