Merge pull request #23346 from drodil/migrate_local_dev

chore: migrate to new backend in local development
This commit is contained in:
Patrik Oldsberg
2024-04-14 13:49:28 +02:00
committed by GitHub
20 changed files with 295 additions and 342 deletions
+10
View File
@@ -13,7 +13,9 @@ import { Entity } from '@backstage/catalog-model';
import { GridProps } from '@material-ui/core/Grid';
import { IconComponent } from '@backstage/core-plugin-api';
import { PropsWithChildren } from 'react';
import { default as React_2 } from 'react';
import { ReactNode } from 'react';
import { SignInProviderConfig } from '@backstage/core-components';
// @public
export function createDevApp(): DevAppBuilder;
@@ -22,6 +24,8 @@ export function createDevApp(): DevAppBuilder;
export class DevAppBuilder {
addPage(opts: DevAppPageOptions): DevAppBuilder;
addRootChild(node: ReactNode): DevAppBuilder;
addSidebarItem(sidebarItem: JSX.Element): DevAppBuilder;
addSignInProvider(provider: SignInProviderConfig): this;
addThemes(themes: AppTheme[]): this;
build(): ComponentType<PropsWithChildren<{}>>;
registerApi<
@@ -50,4 +54,10 @@ export const EntityGridItem: (
entity: Entity;
},
) => JSX.Element;
// @public
export const SidebarSignOutButton: (props: {
icon?: IconComponent;
text?: string;
}) => React_2.JSX.Element;
```
@@ -0,0 +1,44 @@
/*
* Copyright 2024 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';
import { SidebarItem } from '@backstage/core-components';
import LockIcon from '@material-ui/icons/Lock';
import {
IconComponent,
identityApiRef,
useApi,
} from '@backstage/core-plugin-api';
/**
* Button for sidebar that signs out user
*
* @public
*/
export const SidebarSignOutButton = (props: {
icon?: IconComponent;
text?: string;
}) => {
const identityApi = useApi(identityApiRef);
return (
<SidebarItem
onClick={() => identityApi.signOut()}
icon={props.icon ?? LockIcon}
text={props.text ?? 'Sign Out'}
/>
);
};
@@ -0,0 +1,16 @@
/*
* Copyright 2024 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 './SidebarSignOutButton';
@@ -15,3 +15,4 @@
*/
export * from './EntityGridItem';
export * from './SidebarSignOutButton';
@@ -17,7 +17,7 @@
import React from 'react';
import { render } from '@testing-library/react';
import { createDevApp } from './render';
import { useApi, configApiRef } from '@backstage/core-plugin-api';
import { configApiRef, useApi } from '@backstage/core-plugin-api';
const anyEnv = (process.env = { ...process.env }) as any;
@@ -28,6 +28,7 @@ describe('DevAppBuilder', () => {
context: 'test',
data: {
app: { title: 'Test App' },
backend: { baseUrl: 'http://localhost' },
},
},
];
+37 -1
View File
@@ -25,6 +25,8 @@ import {
SidebarPage,
SidebarSpace,
SidebarSpacer,
SignInPage,
SignInProviderConfig,
} from '@backstage/core-components';
import {
AnyApiFactory,
@@ -44,10 +46,11 @@ import {
} from '@backstage/integration-react';
import Box from '@material-ui/core/Box';
import BookmarkIcon from '@material-ui/icons/Bookmark';
import React, { ComponentType, ReactNode, PropsWithChildren } from 'react';
import React, { ComponentType, PropsWithChildren, ReactNode } from 'react';
import { createRoutesFromChildren, Route } from 'react-router-dom';
import { SidebarThemeSwitcher } from './SidebarThemeSwitcher';
import 'react-dom';
import { SidebarSignOutButton } from '../components';
let ReactDOMPromise: Promise<
typeof import('react-dom') | typeof import('react-dom/client')
@@ -94,6 +97,7 @@ export class DevAppBuilder {
private readonly rootChildren = new Array<ReactNode>();
private readonly routes = new Array<JSX.Element>();
private readonly sidebarItems = new Array<JSX.Element>();
private readonly signInProviders = new Array<SignInProviderConfig>();
private defaultPage?: string;
private themes?: Array<AppTheme>;
@@ -128,6 +132,16 @@ export class DevAppBuilder {
return this;
}
/**
* Adds a new sidebar item to the dev app.
*
* Useful for adding only sidebar items without a corresponding page.
*/
addSidebarItem(sidebarItem: JSX.Element): DevAppBuilder {
this.sidebarItems.push(sidebarItem);
return this;
}
/**
* Adds a page component along with accompanying sidebar item.
*
@@ -151,6 +165,7 @@ export class DevAppBuilder {
/>,
);
}
this.routes.push(
<MaybeGatheringRoute
key={path}
@@ -170,6 +185,14 @@ export class DevAppBuilder {
return this;
}
/**
* Adds new sign in provider for the dev app
*/
addSignInProvider(provider: SignInProviderConfig) {
this.signInProviders.push(provider);
return this;
}
/**
* Build a DevApp component using the resources registered so far
*/
@@ -193,6 +216,18 @@ export class DevAppBuilder {
apis,
plugins: this.plugins,
themes: this.themes,
components: {
SignInPage: props => {
return (
<SignInPage
{...props}
providers={['guest', ...this.signInProviders]}
title="Select a sign-in method"
align="center"
/>
);
},
},
bindRoutes: ({ bind }) => {
for (const plugin of this.plugins ?? []) {
const targets: Record<string, RouteRef<any>> = {};
@@ -217,6 +252,7 @@ export class DevAppBuilder {
<SidebarSpace />
<SidebarDivider />
<SidebarThemeSwitcher />
<SidebarSignOutButton />
</Sidebar>
<FlatRoutes>
{this.routes}