Merge pull request #2739 from Marvin9/feat/flexible-theme-for-page
feat: theme customization for pages
This commit is contained in:
@@ -9,7 +9,6 @@ import {
|
||||
InfoCard,
|
||||
Header,
|
||||
Page,
|
||||
pageTheme,
|
||||
Content,
|
||||
ContentHeader,
|
||||
HeaderLabel,
|
||||
@@ -25,7 +24,7 @@ const ExampleComponent: FC<{}> = () => {
|
||||
const profile = identityApi.getProfile();
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<Header
|
||||
title="Welcome to github-playground!"
|
||||
subtitle="Optional subtitle"
|
||||
|
||||
+2
-3
@@ -4,7 +4,6 @@ import {
|
||||
InfoCard,
|
||||
Header,
|
||||
Page,
|
||||
pageTheme,
|
||||
Content,
|
||||
ContentHeader,
|
||||
HeaderLabel,
|
||||
@@ -13,7 +12,7 @@ import {
|
||||
import ExampleFetchComponent from '../ExampleFetchComponent';
|
||||
|
||||
const ExampleComponent: FC<{}> = () => (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<Header title="Welcome to {{ id }}!" subtitle="Optional subtitle">
|
||||
<HeaderLabel label="Owner" value="Team X" />
|
||||
<HeaderLabel label="Lifecycle" value="Alpha" />
|
||||
@@ -37,5 +36,5 @@ const ExampleComponent: FC<{}> = () => (
|
||||
</Content>
|
||||
</Page>
|
||||
);
|
||||
|
||||
|
||||
export default ExampleComponent;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
import React from 'react';
|
||||
import { Header } from '.';
|
||||
import { HeaderLabel } from '../HeaderLabel';
|
||||
import { Page, pageTheme } from '../Page';
|
||||
import { Page } from '../Page';
|
||||
|
||||
export default {
|
||||
title: 'Layout/Header',
|
||||
@@ -32,7 +32,7 @@ const labels = (
|
||||
);
|
||||
|
||||
export const Home = () => (
|
||||
<Page theme={pageTheme.home}>
|
||||
<Page themeId="home">
|
||||
<Header title="Start/Home Page" type="home">
|
||||
{labels}
|
||||
</Header>
|
||||
@@ -46,7 +46,7 @@ export const HomeWithSubtitle = () => (
|
||||
);
|
||||
|
||||
export const Tool = () => (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<Header title="Stand-alone tool" type="tool">
|
||||
{labels}
|
||||
</Header>
|
||||
@@ -54,7 +54,7 @@ export const Tool = () => (
|
||||
);
|
||||
|
||||
export const Service = () => (
|
||||
<Page theme={pageTheme.service}>
|
||||
<Page themeId="service">
|
||||
<Header title="Service component page" type="service">
|
||||
{labels}
|
||||
</Header>
|
||||
@@ -62,7 +62,7 @@ export const Service = () => (
|
||||
);
|
||||
|
||||
export const Website = () => (
|
||||
<Page theme={pageTheme.website}>
|
||||
<Page themeId="website">
|
||||
<Header title="Website component page" type="website">
|
||||
{labels}
|
||||
</Header>
|
||||
@@ -70,7 +70,7 @@ export const Website = () => (
|
||||
);
|
||||
|
||||
export const Library = () => (
|
||||
<Page theme={pageTheme.library}>
|
||||
<Page themeId="library">
|
||||
<Header title="Library component page" type="library">
|
||||
{labels}
|
||||
</Header>
|
||||
@@ -78,7 +78,7 @@ export const Library = () => (
|
||||
);
|
||||
|
||||
export const App = () => (
|
||||
<Page theme={pageTheme.app}>
|
||||
<Page themeId="app">
|
||||
<Header title="App component page" type="app">
|
||||
{labels}
|
||||
</Header>
|
||||
@@ -86,7 +86,7 @@ export const App = () => (
|
||||
);
|
||||
|
||||
export const Documentation = () => (
|
||||
<Page theme={pageTheme.documentation}>
|
||||
<Page themeId="documentation">
|
||||
<Header title="Documentation component page" type="documentation">
|
||||
{labels}
|
||||
</Header>
|
||||
@@ -94,7 +94,7 @@ export const Documentation = () => (
|
||||
);
|
||||
|
||||
export const Other = () => (
|
||||
<Page theme={pageTheme.other}>
|
||||
<Page themeId="other">
|
||||
<Header title="Other/generic component page" type="other">
|
||||
{labels}
|
||||
</Header>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { ReactNode, CSSProperties, FC, useContext } from 'react';
|
||||
import React, { ReactNode, CSSProperties, FC } from 'react';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import {
|
||||
Link,
|
||||
@@ -25,73 +25,70 @@ import {
|
||||
} from '@material-ui/core';
|
||||
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { PageThemeContext } from '../Page/Page';
|
||||
|
||||
const useStyles = makeStyles<BackstageTheme, { backgroundImage: string }>(
|
||||
theme => ({
|
||||
header: {
|
||||
gridArea: 'pageHeader',
|
||||
padding: theme.spacing(3),
|
||||
minHeight: 118,
|
||||
width: '100%',
|
||||
boxShadow: '0 0 8px 3px rgba(20, 20, 20, 0.3)',
|
||||
position: 'relative',
|
||||
zIndex: 100,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'flex-end',
|
||||
alignItems: 'center',
|
||||
backgroundImage: props => props.backgroundImage,
|
||||
backgroundPosition: 'center',
|
||||
backgroundSize: 'cover',
|
||||
},
|
||||
leftItemsBox: {
|
||||
flex: '1 1 auto',
|
||||
},
|
||||
rightItemsBox: {
|
||||
flex: '0 1 auto',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
alignItems: 'center',
|
||||
marginRight: theme.spacing(1),
|
||||
},
|
||||
title: {
|
||||
color: theme.palette.bursts.fontColor,
|
||||
lineHeight: '1.0em',
|
||||
wordBreak: 'break-all',
|
||||
fontSize: 'calc(24px + 6 * ((100vw - 320px) / 680))',
|
||||
marginBottom: theme.spacing(1),
|
||||
},
|
||||
subtitle: {
|
||||
color: 'rgba(255, 255, 255, 0.8)',
|
||||
lineHeight: '1.0em',
|
||||
},
|
||||
type: {
|
||||
textTransform: 'uppercase',
|
||||
fontSize: 11,
|
||||
opacity: 0.8,
|
||||
marginBottom: theme.spacing(1),
|
||||
color: theme.palette.bursts.fontColor,
|
||||
},
|
||||
breadcrumb: {
|
||||
fontSize: 'calc(15px + 1 * ((100vw - 320px) / 680))',
|
||||
color: theme.palette.bursts.fontColor,
|
||||
},
|
||||
breadcrumbType: {
|
||||
fontSize: 'inherit',
|
||||
opacity: 0.7,
|
||||
marginRight: -theme.spacing(0.3),
|
||||
marginBottom: theme.spacing(0.3),
|
||||
},
|
||||
breadcrumbTitle: {
|
||||
fontSize: 'inherit',
|
||||
marginLeft: -theme.spacing(0.3),
|
||||
marginBottom: theme.spacing(0.3),
|
||||
},
|
||||
}),
|
||||
);
|
||||
const useStyles = makeStyles<BackstageTheme>(theme => ({
|
||||
header: {
|
||||
gridArea: 'pageHeader',
|
||||
padding: theme.spacing(3),
|
||||
minHeight: 118,
|
||||
width: '100%',
|
||||
boxShadow: '0 0 8px 3px rgba(20, 20, 20, 0.3)',
|
||||
position: 'relative',
|
||||
zIndex: 100,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'flex-end',
|
||||
alignItems: 'center',
|
||||
backgroundImage: theme.page.backgroundImage,
|
||||
backgroundPosition: 'center',
|
||||
backgroundSize: 'cover',
|
||||
},
|
||||
leftItemsBox: {
|
||||
flex: '1 1 auto',
|
||||
},
|
||||
rightItemsBox: {
|
||||
flex: '0 1 auto',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
alignItems: 'center',
|
||||
marginRight: theme.spacing(1),
|
||||
},
|
||||
title: {
|
||||
color: theme.palette.bursts.fontColor,
|
||||
lineHeight: '1.0em',
|
||||
wordBreak: 'break-all',
|
||||
fontSize: 'calc(24px + 6 * ((100vw - 320px) / 680))',
|
||||
marginBottom: theme.spacing(1),
|
||||
},
|
||||
subtitle: {
|
||||
color: 'rgba(255, 255, 255, 0.8)',
|
||||
lineHeight: '1.0em',
|
||||
},
|
||||
type: {
|
||||
textTransform: 'uppercase',
|
||||
fontSize: 11,
|
||||
opacity: 0.8,
|
||||
marginBottom: theme.spacing(1),
|
||||
color: theme.palette.bursts.fontColor,
|
||||
},
|
||||
breadcrumb: {
|
||||
fontSize: 'calc(15px + 1 * ((100vw - 320px) / 680))',
|
||||
color: theme.palette.bursts.fontColor,
|
||||
},
|
||||
breadcrumbType: {
|
||||
fontSize: 'inherit',
|
||||
opacity: 0.7,
|
||||
marginRight: -theme.spacing(0.3),
|
||||
marginBottom: theme.spacing(0.3),
|
||||
},
|
||||
breadcrumbTitle: {
|
||||
fontSize: 'inherit',
|
||||
marginLeft: -theme.spacing(0.3),
|
||||
marginBottom: theme.spacing(0.3),
|
||||
},
|
||||
}));
|
||||
|
||||
type HeaderStyles = ReturnType<typeof useStyles>;
|
||||
|
||||
@@ -200,8 +197,7 @@ export const Header: FC<Props> = ({
|
||||
type,
|
||||
typeLink,
|
||||
}) => {
|
||||
const theme = useContext(PageThemeContext);
|
||||
const classes = useStyles({ backgroundImage: theme.backgroundImage });
|
||||
const classes = useStyles();
|
||||
const documentTitle = pageTitleOverride || title;
|
||||
const pageTitle = title || pageTitleOverride;
|
||||
const titleTemplate = `${documentTitle} | %s | Backstage`;
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
HeaderLabel,
|
||||
ContentHeader,
|
||||
Content,
|
||||
pageTheme,
|
||||
InfoCard,
|
||||
HeaderTabs,
|
||||
} from '../';
|
||||
@@ -196,7 +195,7 @@ export const PluginWithData = () => {
|
||||
const [selectedTab, setSelectedTab] = useState<number>(2);
|
||||
return (
|
||||
<div style={{ border: '1px solid #ddd' }}>
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<ExampleHeader />
|
||||
<HeaderTabs
|
||||
selectedIndex={selectedTab}
|
||||
@@ -218,7 +217,7 @@ export const PluginWithData = () => {
|
||||
export const PluginWithTable = () => {
|
||||
return (
|
||||
<div style={{ border: '1px solid #ddd' }}>
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<ExampleHeader />
|
||||
<Content>
|
||||
<ExampleContentHeader />
|
||||
|
||||
@@ -15,10 +15,8 @@
|
||||
*/
|
||||
|
||||
import React, { FC } from 'react';
|
||||
import { PageTheme, pageTheme } from './PageThemeProvider';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
|
||||
export const PageThemeContext = React.createContext<PageTheme>(pageTheme.home);
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { makeStyles, ThemeProvider } from '@material-ui/core';
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
root: {
|
||||
@@ -32,14 +30,19 @@ const useStyles = makeStyles(() => ({
|
||||
}));
|
||||
|
||||
type Props = {
|
||||
theme?: PageTheme;
|
||||
themeId: string;
|
||||
};
|
||||
|
||||
export const Page: FC<Props> = ({ theme = pageTheme.home, children }) => {
|
||||
export const Page: FC<Props> = ({ themeId, children }) => {
|
||||
const classes = useStyles();
|
||||
return (
|
||||
<PageThemeContext.Provider value={theme}>
|
||||
<ThemeProvider
|
||||
theme={(baseTheme: BackstageTheme) => ({
|
||||
...baseTheme,
|
||||
page: baseTheme.getPageTheme({ themeId }),
|
||||
})}
|
||||
>
|
||||
<div className={classes.root}>{children}</div>
|
||||
</PageThemeContext.Provider>
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -15,5 +15,3 @@
|
||||
*/
|
||||
|
||||
export { Page } from './Page';
|
||||
export { pageTheme } from './PageThemeProvider';
|
||||
export type { PageTheme } from './PageThemeProvider';
|
||||
|
||||
@@ -52,7 +52,7 @@ export const SignInPage: FC<Props> = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<Page themeId="home">
|
||||
<Header title={configApi.getString('app.title')} />
|
||||
<Content>
|
||||
{title && <ContentHeader title={title} textAlign={align} />}
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
BackstageThemeOptions,
|
||||
SimpleThemeOptions,
|
||||
} from './types';
|
||||
import { pageTheme as defaultPageThemes } from './pageTheme';
|
||||
|
||||
const DEFAULT_FONT_FAMILY =
|
||||
'"Helvetica Neue", Helvetica, Roboto, Arial, sans-serif';
|
||||
@@ -30,7 +31,16 @@ const DEFAULT_FONT_FAMILY =
|
||||
export function createThemeOptions(
|
||||
options: SimpleThemeOptions,
|
||||
): BackstageThemeOptions {
|
||||
const { palette, fontFamily = DEFAULT_FONT_FAMILY } = options;
|
||||
const {
|
||||
palette,
|
||||
fontFamily = DEFAULT_FONT_FAMILY,
|
||||
defaultPageTheme,
|
||||
pageTheme = defaultPageThemes,
|
||||
} = options;
|
||||
|
||||
if (!pageTheme[defaultPageTheme]) {
|
||||
throw new Error(`${defaultPageTheme} is not defined in pageTheme.`);
|
||||
}
|
||||
|
||||
return {
|
||||
palette,
|
||||
@@ -68,6 +78,9 @@ export function createThemeOptions(
|
||||
marginBottom: 10,
|
||||
},
|
||||
},
|
||||
page: pageTheme[defaultPageTheme],
|
||||
getPageTheme: ({ themeId }) =>
|
||||
pageTheme[themeId] ?? pageTheme[defaultPageTheme],
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -17,3 +17,4 @@
|
||||
export * from './themes';
|
||||
export * from './baseTheme';
|
||||
export * from './types';
|
||||
export * from './pageTheme';
|
||||
|
||||
+13
-19
@@ -13,12 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export type PageTheme = {
|
||||
colors: string[];
|
||||
shape: string;
|
||||
backgroundImage: string;
|
||||
};
|
||||
import { PageTheme } from './types';
|
||||
|
||||
/*
|
||||
# How to add a shape
|
||||
@@ -29,7 +24,6 @@ export type PageTheme = {
|
||||
with something like https://npm.runkit.com/mini-svg-data-uri
|
||||
4. Wrap the output in `url("")`
|
||||
5. Give it a name and paste it into the `shapes` object below.
|
||||
|
||||
*/
|
||||
export const shapes: Record<string, string> = {
|
||||
wave: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='1368' height='400' fill='none'%3e%3cmask id='a' width='1368' height='401' x='0' y='0' maskUnits='userSpaceOnUse'%3e%3cpath fill='url(%23paint0_linear)' d='M437 116C223 116 112 0 112 0h1256v400c-82 0-225-21-282-109-112-175-436-175-649-175z'/%3e%3cpath fill='url(%23paint1_linear)' d='M1368 400V282C891-29 788 40 711 161 608 324 121 372 0 361v39h1368z'/%3e%3cpath fill='url(%23paint2_linear)' d='M1368 244v156H0V94c92-24 198-46 375 0l135 41c176 51 195 109 858 109z'/%3e%3cpath fill='url(%23paint3_linear)' d='M1252 400h116c-14-7-35-14-116-16-663-14-837-128-1013-258l-85-61C98 28 46 8 0 0v400h1252z'/%3e%3c/mask%3e%3cg mask='url(%23a)'%3e%3cpath fill='white' d='M-172-98h1671v601H-172z'/%3e%3c/g%3e%3cdefs%3e%3clinearGradient id='paint0_linear' x1='602' x2='1093.5' y1='-960.5' y2='272' gradientUnits='userSpaceOnUse'%3e%3cstop stop-color='white'/%3e%3cstop offset='1' stop-color='white' stop-opacity='0'/%3e%3c/linearGradient%3e%3clinearGradient id='paint1_linear' x1='482' x2='480' y1='1058.5' y2='70.5' gradientUnits='userSpaceOnUse'%3e%3cstop stop-color='white'/%3e%3cstop offset='1' stop-color='white' stop-opacity='0'/%3e%3c/linearGradient%3e%3clinearGradient id='paint2_linear' x1='424' x2='446.1' y1='-587.5' y2='274.6' gradientUnits='userSpaceOnUse'%3e%3cstop stop-color='white'/%3e%3cstop offset='1' stop-color='white' stop-opacity='0'/%3e%3c/linearGradient%3e%3clinearGradient id='paint3_linear' x1='587' x2='349' y1='-1120.5' y2='341' gradientUnits='userSpaceOnUse'%3e%3cstop stop-color='white'/%3e%3cstop offset='1' stop-color='white' stop-opacity='0'/%3e%3c/linearGradient%3e%3c/defs%3e%3c/svg%3e")`,
|
||||
@@ -49,24 +43,24 @@ export const colorVariants: Record<string, string[]> = {
|
||||
pinkSea: ['#C8077A', '#C2297D'],
|
||||
};
|
||||
|
||||
export const pageTheme: Record<string, PageTheme> = {
|
||||
home: genTheme(colorVariants.teal, shapes.wave),
|
||||
documentation: genTheme(colorVariants.pinkSea, shapes.wave2),
|
||||
tool: genTheme(colorVariants.purpleSky, shapes.round),
|
||||
service: genTheme(colorVariants.marineBlue, shapes.wave),
|
||||
website: genTheme(colorVariants.veryBlue, shapes.wave),
|
||||
library: genTheme(colorVariants.rubyRed, shapes.wave),
|
||||
other: genTheme(colorVariants.darkGrey, shapes.wave),
|
||||
app: genTheme(colorVariants.toastyOrange, shapes.wave),
|
||||
};
|
||||
|
||||
// As the background shapes and colors are decorative, we place them onto
|
||||
// the page as a css background-image instead of an html element of its own.
|
||||
// Utility to not have to write colors and shapes twice.
|
||||
function genTheme(colors: string[], shape: string) {
|
||||
export function genPageTheme(colors: string[], shape: string): PageTheme {
|
||||
const gradientColors = colors.length === 1 ? [colors[0], colors[0]] : colors;
|
||||
const gradient = `linear-gradient(90deg, ${gradientColors.join(', ')})`;
|
||||
const backgroundImage = `${shape}, ${gradient}`;
|
||||
|
||||
return { colors, shape, backgroundImage };
|
||||
}
|
||||
|
||||
export const pageTheme: Record<string, PageTheme> = {
|
||||
home: genPageTheme(colorVariants.teal, shapes.wave),
|
||||
documentation: genPageTheme(colorVariants.pinkSea, shapes.wave2),
|
||||
tool: genPageTheme(colorVariants.purpleSky, shapes.round),
|
||||
service: genPageTheme(colorVariants.marineBlue, shapes.wave),
|
||||
website: genPageTheme(colorVariants.veryBlue, shapes.wave),
|
||||
library: genPageTheme(colorVariants.rubyRed, shapes.wave),
|
||||
other: genPageTheme(colorVariants.darkGrey, shapes.wave),
|
||||
app: genPageTheme(colorVariants.toastyOrange, shapes.wave),
|
||||
};
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import { createTheme } from './baseTheme';
|
||||
import { pageTheme } from './pageTheme';
|
||||
import { yellow } from '@material-ui/core/colors';
|
||||
|
||||
export const lightTheme = createTheme({
|
||||
@@ -75,6 +76,8 @@ export const lightTheme = createTheme({
|
||||
indicator: '#9BF0E1',
|
||||
},
|
||||
},
|
||||
defaultPageTheme: 'home',
|
||||
pageTheme,
|
||||
});
|
||||
|
||||
export const darkTheme = createTheme({
|
||||
@@ -135,4 +138,6 @@ export const darkTheme = createTheme({
|
||||
indicator: '#9BF0E1',
|
||||
},
|
||||
},
|
||||
defaultPageTheme: 'home',
|
||||
pageTheme,
|
||||
});
|
||||
|
||||
@@ -74,12 +74,20 @@ type PaletteAdditions = {
|
||||
export type BackstagePalette = Palette & PaletteAdditions;
|
||||
export type BackstagePaletteOptions = PaletteOptions & PaletteAdditions;
|
||||
|
||||
export type PageThemeSelector = {
|
||||
themeId: string;
|
||||
};
|
||||
|
||||
export interface BackstageTheme extends Theme {
|
||||
palette: BackstagePalette;
|
||||
page: PageTheme;
|
||||
getPageTheme: ({ themeId }: PageThemeSelector) => PageTheme;
|
||||
}
|
||||
|
||||
export interface BackstageThemeOptions extends ThemeOptions {
|
||||
palette: BackstagePaletteOptions;
|
||||
page: PageTheme;
|
||||
getPageTheme: ({ themeId }: PageThemeSelector) => PageTheme;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,5 +95,13 @@ export interface BackstageThemeOptions extends ThemeOptions {
|
||||
*/
|
||||
export type SimpleThemeOptions = {
|
||||
palette: BackstagePaletteOptions;
|
||||
defaultPageTheme: string;
|
||||
pageTheme?: Record<string, PageTheme>;
|
||||
fontFamily?: string;
|
||||
};
|
||||
|
||||
export type PageTheme = {
|
||||
colors: string[];
|
||||
shape: string;
|
||||
backgroundImage: string;
|
||||
};
|
||||
|
||||
@@ -13,14 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { ApiProvider, ApiRegistry, errorApiRef } from '@backstage/core';
|
||||
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
import { render, waitFor } from '@testing-library/react';
|
||||
import * as React from 'react';
|
||||
import { ApiEntityPage, getPageTheme } from './ApiEntityPage';
|
||||
import { ApiEntityPage } from './ApiEntityPage';
|
||||
|
||||
jest.mock('react-router-dom', () => {
|
||||
const actual = jest.requireActual('react-router-dom');
|
||||
@@ -71,32 +69,3 @@ describe('ApiEntityPage', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getPageTheme', () => {
|
||||
const defaultPageTheme = getPageTheme();
|
||||
it.each(['service', 'app', 'library', 'tool', 'documentation', 'website'])(
|
||||
'should select right theme for predefined type: %p ̰ ',
|
||||
type => {
|
||||
const theme = getPageTheme(({
|
||||
spec: {
|
||||
type,
|
||||
},
|
||||
} as any) as Entity);
|
||||
expect(theme).toBeDefined();
|
||||
expect(theme).not.toBe(defaultPageTheme);
|
||||
},
|
||||
);
|
||||
|
||||
it('should select default theme for unknown/unspecified types', () => {
|
||||
const theme1 = getPageTheme(({
|
||||
spec: {
|
||||
type: 'unknown-type',
|
||||
},
|
||||
} as any) as Entity);
|
||||
const theme2 = getPageTheme(({
|
||||
spec: {},
|
||||
} as any) as Entity);
|
||||
expect(theme1).toBe(defaultPageTheme);
|
||||
expect(theme2).toBe(defaultPageTheme);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,8 +20,6 @@ import {
|
||||
errorApiRef,
|
||||
Header,
|
||||
Page,
|
||||
pageTheme,
|
||||
PageTheme,
|
||||
Progress,
|
||||
useApi,
|
||||
} from '@backstage/core';
|
||||
@@ -54,11 +52,6 @@ function headerProps(
|
||||
};
|
||||
}
|
||||
|
||||
export const getPageTheme = (entity?: Entity): PageTheme => {
|
||||
const themeKey = entity?.spec?.type?.toString() ?? 'home';
|
||||
return pageTheme[themeKey] ?? pageTheme.home;
|
||||
};
|
||||
|
||||
type EntityPageTitleProps = {
|
||||
title: string;
|
||||
entity: Entity | undefined;
|
||||
@@ -107,7 +100,7 @@ export const ApiEntityPage = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<Page theme={getPageTheme(entity)}>
|
||||
<Page themeId={entity?.spec?.type?.toString() ?? 'home'}>
|
||||
<Header
|
||||
title={<EntityPageTitle title={headerTitle} entity={entity} />}
|
||||
pageTitleOverride={headerTitle}
|
||||
|
||||
@@ -14,22 +14,20 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Header, Page, pageTheme } from '@backstage/core';
|
||||
import { Header, Page } from '@backstage/core';
|
||||
import React from 'react';
|
||||
|
||||
type Props = {
|
||||
children?: React.ReactNode;
|
||||
};
|
||||
|
||||
export const ApiExplorerLayout = ({ children }: Props) => {
|
||||
return (
|
||||
<Page theme={pageTheme.home}>
|
||||
<Header
|
||||
title="APIs"
|
||||
subtitle="Backstage API Explorer"
|
||||
pageTitleOverride="APIs"
|
||||
/>
|
||||
{children}
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
export const ApiExplorerLayout = ({ children }: Props) => (
|
||||
<Page themeId="home">
|
||||
<Header
|
||||
title="APIs"
|
||||
subtitle="Backstage API Explorer"
|
||||
pageTitleOverride="APIs"
|
||||
/>
|
||||
{children}
|
||||
</Page>
|
||||
);
|
||||
|
||||
@@ -20,7 +20,6 @@ import {
|
||||
HomepageTimer,
|
||||
identityApiRef,
|
||||
Page,
|
||||
pageTheme,
|
||||
useApi,
|
||||
} from '@backstage/core';
|
||||
import React from 'react';
|
||||
@@ -37,7 +36,7 @@ const CatalogLayout = ({ children }: Props) => {
|
||||
const orgName = useApi(configApiRef).getOptionalString('organization.name');
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.home}>
|
||||
<Page themeId="home">
|
||||
<Header
|
||||
title={`${greeting.greeting}, ${profile.displayName || userId}!`}
|
||||
subtitle={`${orgName || 'Backstage'} Service Catalog`}
|
||||
|
||||
@@ -17,15 +17,7 @@ import React, { useState, useContext } from 'react';
|
||||
import { useParams, useNavigate } from 'react-router';
|
||||
|
||||
import { EntityContext } from '../../hooks/useEntity';
|
||||
import {
|
||||
pageTheme,
|
||||
PageTheme,
|
||||
Page,
|
||||
Header,
|
||||
HeaderLabel,
|
||||
Content,
|
||||
Progress,
|
||||
} from '@backstage/core';
|
||||
import { Page, Header, HeaderLabel, Content, Progress } from '@backstage/core';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { FavouriteEntity } from '../FavouriteEntity/FavouriteEntity';
|
||||
import { Box } from '@material-ui/core';
|
||||
@@ -34,11 +26,6 @@ import { UnregisterEntityDialog } from '../UnregisterEntityDialog/UnregisterEnti
|
||||
import { Alert } from '@material-ui/lab';
|
||||
import { Tabbed } from './Tabbed';
|
||||
|
||||
const getPageTheme = (entity?: Entity): PageTheme => {
|
||||
const themeKey = entity?.spec?.type?.toString() ?? 'home';
|
||||
return pageTheme[themeKey] ?? pageTheme.home;
|
||||
};
|
||||
|
||||
const EntityPageTitle = ({
|
||||
entity,
|
||||
title,
|
||||
@@ -100,7 +87,7 @@ export const EntityPageLayout = ({
|
||||
const showRemovalDialog = () => setConfirmationDialogOpen(true);
|
||||
|
||||
return (
|
||||
<Page theme={getPageTheme(entity!)}>
|
||||
<Page themeId={entity?.spec?.type?.toString() ?? 'home'}>
|
||||
<Header
|
||||
title={<EntityPageTitle title={headerTitle} entity={entity!} />}
|
||||
pageTitleOverride={headerTitle}
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import { Box, Button, Container, makeStyles } from '@material-ui/core';
|
||||
import ChevronLeftIcon from '@material-ui/icons/ChevronLeft';
|
||||
import { Header, Page, pageTheme } from '@backstage/core';
|
||||
import { Header, Page } from '@backstage/core';
|
||||
import { CostInsightsThemeProvider } from '../CostInsightsPage/CostInsightsThemeProvider';
|
||||
import { ConfigProvider, CurrencyProvider } from '../../hooks';
|
||||
|
||||
@@ -42,7 +42,7 @@ const AlertInstructionsLayout = ({
|
||||
<CostInsightsThemeProvider>
|
||||
<ConfigProvider>
|
||||
<CurrencyProvider>
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<Header
|
||||
title="Cost Insights"
|
||||
pageTitleOverride={title}
|
||||
|
||||
@@ -13,10 +13,9 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import { Header, Page, pageTheme } from '@backstage/core';
|
||||
import { Header, Page } from '@backstage/core';
|
||||
import { Group } from '../../types';
|
||||
import CostInsightsTabs from '../CostInsightsTabs';
|
||||
|
||||
@@ -41,7 +40,7 @@ type CostInsightsLayoutProps = {
|
||||
const CostInsightsLayout = ({ groups, children }: CostInsightsLayoutProps) => {
|
||||
const classes = useStyles();
|
||||
return (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<Header
|
||||
style={{ boxShadow: 'none' }}
|
||||
title="Cost Insights"
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
ContentHeader,
|
||||
Header,
|
||||
Page,
|
||||
pageTheme,
|
||||
SupportButton,
|
||||
} from '@backstage/core';
|
||||
import ExploreCard, { CardData } from './ExploreCard';
|
||||
@@ -116,8 +115,9 @@ const toolsCards = [
|
||||
|
||||
export const ExplorePluginPage = () => {
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.home}>
|
||||
<Page themeId="home">
|
||||
<Header
|
||||
title="Explore"
|
||||
subtitle="Tools and services available in Backstage"
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
HeaderLabel,
|
||||
InfoCard,
|
||||
Page,
|
||||
pageTheme,
|
||||
SimpleStepper,
|
||||
SimpleStepperStep,
|
||||
StructuredMetadataTable,
|
||||
@@ -111,20 +110,18 @@ const labels = (
|
||||
</>
|
||||
);
|
||||
|
||||
export const NewProjectPage = () => {
|
||||
return (
|
||||
<Page theme={pageTheme.service}>
|
||||
<Header title="New GCP Project" type="tool">
|
||||
{labels}
|
||||
</Header>
|
||||
<Content>
|
||||
<ContentHeader title="">
|
||||
<SupportButton>
|
||||
This plugin allows you to view and interact with your gcp projects.
|
||||
</SupportButton>
|
||||
</ContentHeader>
|
||||
<Project />
|
||||
</Content>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
export const NewProjectPage = () => (
|
||||
<Page themeId="service">
|
||||
<Header title="New GCP Project" type="tool">
|
||||
{labels}
|
||||
</Header>
|
||||
<Content>
|
||||
<ContentHeader title="">
|
||||
<SupportButton>
|
||||
This plugin allows you to view and interact with your gcp projects.
|
||||
</SupportButton>
|
||||
</ContentHeader>
|
||||
<Project />
|
||||
</Content>
|
||||
</Page>
|
||||
);
|
||||
|
||||
@@ -13,14 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Content,
|
||||
ContentHeader,
|
||||
Header,
|
||||
HeaderLabel,
|
||||
Page,
|
||||
pageTheme,
|
||||
SupportButton,
|
||||
useApi,
|
||||
WarningPanel,
|
||||
@@ -147,18 +145,16 @@ const labels = (
|
||||
</>
|
||||
);
|
||||
|
||||
export const ProjectDetailsPage = () => {
|
||||
return (
|
||||
<Page theme={pageTheme.service}>
|
||||
<Header title="GCP Project Details" type="other">
|
||||
{labels}
|
||||
</Header>
|
||||
<Content>
|
||||
<ContentHeader title="">
|
||||
<SupportButton>Support Button</SupportButton>
|
||||
</ContentHeader>
|
||||
<DetailsPage />
|
||||
</Content>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
export const ProjectDetailsPage = () => (
|
||||
<Page themeId="service">
|
||||
<Header title="GCP Project Details" type="other">
|
||||
{labels}
|
||||
</Header>
|
||||
<Content>
|
||||
<ContentHeader title="">
|
||||
<SupportButton>Support Button</SupportButton>
|
||||
</ContentHeader>
|
||||
<DetailsPage />
|
||||
</Content>
|
||||
</Page>
|
||||
);
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
// NEEDS WORK
|
||||
|
||||
import {
|
||||
Content,
|
||||
ContentHeader,
|
||||
@@ -23,7 +22,6 @@ import {
|
||||
HeaderLabel,
|
||||
Link,
|
||||
Page,
|
||||
pageTheme,
|
||||
SupportButton,
|
||||
useApi,
|
||||
WarningPanel,
|
||||
@@ -134,21 +132,19 @@ const PageContents = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export const ProjectListPage = () => {
|
||||
return (
|
||||
<Page theme={pageTheme.service}>
|
||||
<Header title="GCP Projects" type="tool">
|
||||
{labels}
|
||||
</Header>
|
||||
<Content>
|
||||
<ContentHeader title="">
|
||||
<Button variant="contained" color="primary" href="/gcp-projects/new">
|
||||
New Project
|
||||
</Button>
|
||||
<SupportButton>All your software catalog entities</SupportButton>
|
||||
</ContentHeader>
|
||||
<PageContents />
|
||||
</Content>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
export const ProjectListPage = () => (
|
||||
<Page themeId="service">
|
||||
<Header title="GCP Projects" type="tool">
|
||||
{labels}
|
||||
</Header>
|
||||
<Content>
|
||||
<ContentHeader title="">
|
||||
<Button variant="contained" color="primary" href="/gcp-projects/new">
|
||||
New Project
|
||||
</Button>
|
||||
<SupportButton>All your software catalog entities</SupportButton>
|
||||
</ContentHeader>
|
||||
<PageContents />
|
||||
</Content>
|
||||
</Page>
|
||||
);
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
Header,
|
||||
SupportButton,
|
||||
Page,
|
||||
pageTheme,
|
||||
Progress,
|
||||
HeaderLabel,
|
||||
useApi,
|
||||
@@ -91,7 +90,7 @@ const ClusterList: FC<{}> = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.home}>
|
||||
<Page themeId="home">
|
||||
<Header title="GitOps-managed Clusters">
|
||||
<HeaderLabel label="Welcome" value={githubUsername} />
|
||||
</Header>
|
||||
|
||||
@@ -13,13 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { FC, useEffect, useState } from 'react';
|
||||
import {
|
||||
Content,
|
||||
Header,
|
||||
Page,
|
||||
pageTheme,
|
||||
Table,
|
||||
Progress,
|
||||
HeaderLabel,
|
||||
@@ -85,7 +83,7 @@ const ClusterPage: FC<{}> = () => {
|
||||
}, [pollingLog, api, params, githubAuth, githubAccessToken, githubUsername]);
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.home}>
|
||||
<Page themeId="home">
|
||||
<Header title={`Cluster ${params.owner}/${params.repo}`}>
|
||||
<HeaderLabel label="Welcome" value={githubUsername} />
|
||||
</Header>
|
||||
|
||||
@@ -18,7 +18,6 @@ import React, { FC, useEffect, useState } from 'react';
|
||||
import {
|
||||
Header,
|
||||
Page,
|
||||
pageTheme,
|
||||
Content,
|
||||
ContentHeader,
|
||||
HeaderLabel,
|
||||
@@ -259,7 +258,7 @@ const ProfileCatalog: FC<{}> = () => {
|
||||
];
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<Header
|
||||
title="Create GitOps-managed Cluster"
|
||||
subtitle="Kubernetes cluster with ready-to-use profiles"
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {
|
||||
Content,
|
||||
@@ -21,7 +20,6 @@ import {
|
||||
HeaderLabel,
|
||||
Page,
|
||||
Progress,
|
||||
pageTheme,
|
||||
useApi,
|
||||
} from '@backstage/core';
|
||||
import { useAsync } from 'react-use';
|
||||
@@ -60,7 +58,7 @@ export const GraphiQLPage = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<Header title="GraphiQL">
|
||||
<HeaderLabel label="Owner" value="Spotify" />
|
||||
<HeaderLabel label="Lifecycle" value="Alpha" />
|
||||
|
||||
@@ -22,7 +22,6 @@ import {
|
||||
configApiRef,
|
||||
Content,
|
||||
Page,
|
||||
pageTheme,
|
||||
Progress,
|
||||
TabbedCard,
|
||||
useApi,
|
||||
@@ -148,7 +147,7 @@ export const KubernetesContent = ({ entity }: KubernetesContentProps) => {
|
||||
kubernetesObjects?.items.filter(r => r.errors.length > 0) ?? [];
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<Content>
|
||||
<Grid container spacing={3} direction="column">
|
||||
{kubernetesObjects === undefined && error === undefined && (
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useState, useMemo, FC, ReactNode } from 'react';
|
||||
import { useLocalStorage, useAsync } from 'react-use';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
@@ -28,7 +27,6 @@ import {
|
||||
ContentHeader,
|
||||
HeaderLabel,
|
||||
Progress,
|
||||
pageTheme,
|
||||
useApi,
|
||||
} from '@backstage/core';
|
||||
|
||||
@@ -95,7 +93,7 @@ const AuditList: FC<{}> = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<Header
|
||||
title="Lighthouse"
|
||||
subtitle="Website audits powered by Lighthouse"
|
||||
|
||||
@@ -34,7 +34,6 @@ import {
|
||||
import Alert from '@material-ui/lab/Alert';
|
||||
import {
|
||||
useApi,
|
||||
pageTheme,
|
||||
InfoCard,
|
||||
Header,
|
||||
Page,
|
||||
@@ -193,7 +192,7 @@ export const AuditViewContent: FC<{}> = () => {
|
||||
};
|
||||
|
||||
const ConnectedAuditView = () => (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<Header title="Lighthouse" subtitle="Website audits powered by Lighthouse">
|
||||
<HeaderLabel label="Owner" value="Spotify" />
|
||||
<HeaderLabel label="Lifecycle" value="Alpha" />
|
||||
|
||||
@@ -30,7 +30,6 @@ import {
|
||||
InfoCard,
|
||||
Header,
|
||||
Page,
|
||||
pageTheme,
|
||||
Content,
|
||||
ContentHeader,
|
||||
HeaderLabel,
|
||||
@@ -170,7 +169,7 @@ export const CreateAuditContent: FC<{}> = () => {
|
||||
};
|
||||
|
||||
const CreateAudit = () => (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<Header title="Lighthouse" subtitle="Website audits powered by Lighthouse">
|
||||
<HeaderLabel label="Owner" value="Spotify" />
|
||||
<HeaderLabel label="Lifecycle" value="Alpha" />
|
||||
|
||||
@@ -19,7 +19,6 @@ import { Grid } from '@material-ui/core';
|
||||
import {
|
||||
Header,
|
||||
Page,
|
||||
pageTheme,
|
||||
Content,
|
||||
ContentHeader,
|
||||
HeaderLabel,
|
||||
@@ -28,7 +27,7 @@ import {
|
||||
import NewRelicFetchComponent from '../NewRelicFetchComponent';
|
||||
|
||||
const NewRelicComponent: FC<{}> = () => (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<Header title="New Relic">
|
||||
<HeaderLabel label="Owner" value="Engineering" />
|
||||
</Header>
|
||||
|
||||
+1
-2
@@ -19,7 +19,6 @@ import { Grid, makeStyles } from '@material-ui/core';
|
||||
import {
|
||||
InfoCard,
|
||||
Page,
|
||||
pageTheme,
|
||||
Content,
|
||||
useApi,
|
||||
errorApiRef,
|
||||
@@ -113,7 +112,7 @@ export const RegisterComponentPage = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.home}>
|
||||
<Page themeId="home">
|
||||
<Header title="Register existing component" />
|
||||
<Content>
|
||||
<ContentHeader title="Start tracking your component in Backstage">
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Content, Header, Page, pageTheme } from '@backstage/core';
|
||||
import { Content, Header, Page } from '@backstage/core';
|
||||
import { RollbarProjectTable } from '../RollbarProjectTable/RollbarProjectTable';
|
||||
import { useRollbarEntities } from '../../hooks/useRollbarEntities';
|
||||
|
||||
@@ -23,7 +23,7 @@ export const RollbarHome = () => {
|
||||
const { entities, loading, error } = useRollbarEntities();
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<Header
|
||||
title="Rollbar"
|
||||
subtitle="Real-time error tracking & debugging tools for developers"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Content, Header, HeaderLabel, Page, pageTheme } from '@backstage/core';
|
||||
import { Content, Header, HeaderLabel, Page } from '@backstage/core';
|
||||
import { useCatalogEntity } from '../../hooks/useCatalogEntity';
|
||||
import { RollbarProject } from '../RollbarProject/RollbarProject';
|
||||
|
||||
@@ -23,7 +23,7 @@ export const RollbarProjectPage = () => {
|
||||
const { entity } = useCatalogEntity();
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<Header title={entity?.metadata?.name} subtitle="Rollbar Project">
|
||||
<HeaderLabel label="Owner" value={entity?.spec?.owner} />
|
||||
<HeaderLabel label="Lifecycle" value={entity?.spec?.lifecycle} />
|
||||
|
||||
@@ -22,7 +22,6 @@ import {
|
||||
Header,
|
||||
Lifecycle,
|
||||
Page,
|
||||
pageTheme,
|
||||
Progress,
|
||||
SupportButton,
|
||||
useApi,
|
||||
@@ -66,7 +65,7 @@ export const ScaffolderPage = () => {
|
||||
}, [error, errorApi]);
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.home}>
|
||||
<Page themeId="home">
|
||||
<Header
|
||||
pageTitleOverride="Create a New Component"
|
||||
title={
|
||||
|
||||
@@ -13,8 +13,15 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Button, pageTheme } from '@backstage/core';
|
||||
import { Card, Chip, makeStyles, Typography } from '@material-ui/core';
|
||||
import { Button } from '@backstage/core';
|
||||
import { BackstageTheme, pageTheme } from '@backstage/theme';
|
||||
import {
|
||||
Card,
|
||||
Chip,
|
||||
makeStyles,
|
||||
Typography,
|
||||
useTheme,
|
||||
} from '@material-ui/core';
|
||||
import React from 'react';
|
||||
import { generatePath } from 'react-router-dom';
|
||||
import { templateRoute } from '../../routes';
|
||||
@@ -56,7 +63,10 @@ export const TemplateCard = ({
|
||||
type,
|
||||
name,
|
||||
}: TemplateCardProps) => {
|
||||
const theme = pageTheme[type] ?? pageTheme.other;
|
||||
const backstageTheme = useTheme<BackstageTheme>();
|
||||
|
||||
const themeId = pageTheme[type] ? type : 'other';
|
||||
const theme = backstageTheme.getPageTheme({ themeId });
|
||||
const classes = useStyles({ backgroundImage: theme.backgroundImage });
|
||||
const href = generatePath(templateRoute.path, { templateName: name });
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import {
|
||||
Lifecycle,
|
||||
Page,
|
||||
useApi,
|
||||
pageTheme,
|
||||
} from '@backstage/core';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog';
|
||||
import { LinearProgress } from '@material-ui/core';
|
||||
@@ -145,7 +144,7 @@ export const TemplatePage = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.home}>
|
||||
<Page themeId="home">
|
||||
<Header
|
||||
pageTitleOverride="Create a new component"
|
||||
title={
|
||||
|
||||
@@ -19,7 +19,6 @@ import { Grid } from '@material-ui/core';
|
||||
import {
|
||||
Header,
|
||||
Page,
|
||||
pageTheme,
|
||||
Content,
|
||||
ContentHeader,
|
||||
SupportButton,
|
||||
@@ -33,7 +32,7 @@ const SentryPluginPage: FC<{}> = () => {
|
||||
const sentryProjectId = 'sample-sentry-project-id';
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<Header title="Sentry" />
|
||||
<Content>
|
||||
<ContentHeader title="Issue on Sentry">
|
||||
|
||||
@@ -23,7 +23,6 @@ import {
|
||||
Header,
|
||||
HeaderLabel,
|
||||
SupportButton,
|
||||
pageTheme,
|
||||
} from '@backstage/core';
|
||||
import RadarComponent from '../components/RadarComponent';
|
||||
import { TechRadarComponentProps } from '../api';
|
||||
@@ -40,7 +39,7 @@ export const RadarPage = ({
|
||||
pageTitle,
|
||||
...props
|
||||
}: TechRadarPageProps): JSX.Element => (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Page themeId="tool">
|
||||
<Header title={title} subtitle={subtitle}>
|
||||
<HeaderLabel label="Owner" value="Spotify" />
|
||||
<HeaderLabel label="Lifecycle" value="Beta" />
|
||||
|
||||
@@ -24,7 +24,6 @@ import {
|
||||
useApi,
|
||||
Content,
|
||||
Page,
|
||||
pageTheme,
|
||||
Header,
|
||||
} from '@backstage/core';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog';
|
||||
@@ -43,7 +42,7 @@ export const TechDocsHome = () => {
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<Page theme={pageTheme.documentation}>
|
||||
<Page themeId="documentation">
|
||||
<Header
|
||||
title="Documentation"
|
||||
subtitle="Documentation available in Backstage"
|
||||
@@ -57,7 +56,7 @@ export const TechDocsHome = () => {
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<Page theme={pageTheme.documentation}>
|
||||
<Page themeId="documentation">
|
||||
<Header
|
||||
title="Documentation"
|
||||
subtitle="Documentation available in Backstage"
|
||||
@@ -70,7 +69,7 @@ export const TechDocsHome = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.documentation}>
|
||||
<Page themeId="documentation">
|
||||
<Header
|
||||
title="Documentation"
|
||||
subtitle="Documentation available in Backstage"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { Content, Page, pageTheme, useApi } from '@backstage/core';
|
||||
import { Content, Page, useApi } from '@backstage/core';
|
||||
import { Reader } from './Reader';
|
||||
import { useAsync } from 'react-use';
|
||||
import { TechDocsPageHeader } from './TechDocsPageHeader';
|
||||
@@ -45,7 +45,7 @@ export const TechDocsPage = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.documentation}>
|
||||
<Page themeId="documentation">
|
||||
<TechDocsPageHeader
|
||||
metadataRequest={{
|
||||
mkdocs: mkdocsMetadataRequest,
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { Content, Header, HeaderTabs, Page, pageTheme } from '@backstage/core';
|
||||
import { Content, Header, HeaderTabs, Page } from '@backstage/core';
|
||||
import { General } from './General';
|
||||
import { AuthProviders } from './AuthProviders';
|
||||
import { FeatureFlags } from './FeatureFlags';
|
||||
@@ -43,7 +43,7 @@ export const SettingsPage = ({ providerSettings }: Props) => {
|
||||
];
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.home}>
|
||||
<Page themeId="home">
|
||||
<Header title="Settings" />
|
||||
<HeaderTabs tabs={tabs} onChange={onTabChange} />
|
||||
<Content>{content[activeTab]}</Content>
|
||||
|
||||
@@ -30,7 +30,6 @@ import {
|
||||
Header,
|
||||
HomepageTimer,
|
||||
Page,
|
||||
pageTheme,
|
||||
ContentHeader,
|
||||
SupportButton,
|
||||
WarningPanel,
|
||||
@@ -44,7 +43,7 @@ const WelcomePage = () => {
|
||||
const profile = { givenName: '' };
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.home}>
|
||||
<Page themeId="home">
|
||||
<Header
|
||||
title={`Welcome ${profile.givenName || `to ${appTitle}`}`}
|
||||
subtitle="Let's start building a better developer experience"
|
||||
|
||||
Reference in New Issue
Block a user