app-api: sync with core at master@e9e70677

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2021-05-27 00:27:12 +02:00
parent 41c8e3d35f
commit 6cf2ab47ea
2 changed files with 45 additions and 6 deletions
+24 -1
View File
@@ -14,7 +14,10 @@
* limitations under the License.
*/
import { defaultConfigLoader } from './createApp';
import { render } from '@testing-library/react';
import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { defaultConfigLoader, OptionallyWrapInRouter } from './createApp';
(process as any).env = { NODE_ENV: 'test' };
const anyEnv = process.env as any;
@@ -92,3 +95,23 @@ describe('defaultConfigLoader', () => {
]);
});
});
describe('OptionallyWrapInRouter', () => {
it('should wrap with router if not yet inside a router', async () => {
const { getByText } = render(
<OptionallyWrapInRouter>Test</OptionallyWrapInRouter>,
);
expect(getByText('Test')).toBeInTheDocument();
});
it('should not wrap with router if already inside a router', async () => {
const { getByText } = render(
<MemoryRouter>
<OptionallyWrapInRouter>Test</OptionallyWrapInRouter>
</MemoryRouter>,
);
expect(getByText('Test')).toBeInTheDocument();
});
});
+21 -5
View File
@@ -14,10 +14,14 @@
* limitations under the License.
*/
import React from 'react';
import React, { PropsWithChildren } from 'react';
import { AppOptions, BootErrorPageProps, AppConfigLoader } from './types';
import { defaultAppIcons } from './icons';
import { BrowserRouter, MemoryRouter } from 'react-router-dom';
import {
BrowserRouter,
MemoryRouter,
useInRouterContext,
} from 'react-router-dom';
import LightIcon from '@material-ui/icons/WbSunny';
import DarkIcon from '@material-ui/icons/Brightness2';
import { ErrorPage, Progress } from '@backstage/components';
@@ -52,7 +56,10 @@ export const defaultConfigLoader: AppConfigLoader = async (
const configs = (appConfig.slice() as unknown) as AppConfig[];
// Avoiding this string also being replaced at runtime
if (runtimeConfigJson !== '__app_injected_runtime_config__'.toUpperCase()) {
if (
runtimeConfigJson !==
'__app_injected_runtime_config__'.toLocaleUpperCase('en-US')
) {
try {
const data = JSON.parse(runtimeConfigJson) as JsonObject;
if (Array.isArray(data)) {
@@ -80,6 +87,13 @@ export const defaultConfigLoader: AppConfigLoader = async (
// The actual implementation of the app class still lives in core-api,
// as it needs to be used by dev- and test-utils.
export function OptionallyWrapInRouter({ children }: PropsWithChildren<{}>) {
if (useInRouterContext()) {
return <>{children}</>;
}
return <MemoryRouter>{children}</MemoryRouter>;
}
/**
* Creates a new Backstage App.
*/
@@ -91,12 +105,14 @@ export function createApp(options?: AppOptions) {
let message = '';
if (step === 'load-config') {
message = `The configuration failed to load, someone should have a look at this error: ${error.message}`;
} else if (step === 'load-chunk') {
message = `Lazy loaded chunk failed to load, try to reload the page: ${error.message}`;
}
// TODO: figure out a nicer way to handle routing on the error page, when it can be done.
return (
<MemoryRouter>
<OptionallyWrapInRouter>
<ErrorPage status="501" statusMessage={message} />
</MemoryRouter>
</OptionallyWrapInRouter>
);
};